Passed
Push — master ( 3cffbe...0f9140 )
by Alxarafe
23:50
created

Base/Form.php (37 issues)

1
<?php
2
/* Copyright (c) 2002-2007  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2004-2012  Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
5
 * Copyright (C) 2004       Sebastien Di Cintio     <[email protected]>
6
 * Copyright (C) 2004       Eric Seigne             <[email protected]>
7
 * Copyright (C) 2005-2017  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2006       Andre Cianfarani        <[email protected]>
9
 * Copyright (C) 2006       Marc Barilley/Ocebo     <[email protected]>
10
 * Copyright (C) 2007       Franky Van Liedekerke   <[email protected]>
11
 * Copyright (C) 2007       Patrick Raguin          <[email protected]>
12
 * Copyright (C) 2010       Juanjo Menent           <[email protected]>
13
 * Copyright (C) 2010-2014  Philippe Grand          <[email protected]>
14
 * Copyright (C) 2011       Herve Prot              <[email protected]>
15
 * Copyright (C) 2012-2016  Marcos García           <[email protected]>
16
 * Copyright (C) 2012       Cedric Salvador         <[email protected]>
17
 * Copyright (C) 2012-2015  Raphaël Doursenaud      <[email protected]>
18
 * Copyright (C) 2014       Alexandre Spangaro      <[email protected]>
19
 * Copyright (C) 2018       Ferran Marcet           <[email protected]>
20
 * Copyright (C) 2018       Frédéric France         <[email protected]>
21
 * Copyright (C) 2018       Nicolas ZABOURI	        <[email protected]>
22
 * Copyright (C) 2018       Christophe Battarel     <[email protected]>
23
 * Copyright (C) 2018       Josep Lluis Amador      <[email protected]>
24
 * Copyright (C) 2018-2019  Alxarafe                <[email protected]>
25
 *
26
 * This program is free software; you can redistribute it and/or modify
27
 * it under the terms of the GNU General Public License as published by
28
 * the Free Software Foundation; either version 3 of the License, or
29
 * (at your option) any later version.
30
 *
31
 * This program is distributed in the hope that it will be useful,
32
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
 * GNU General Public License for more details.
35
 *
36
 * You should have received a copy of the GNU General Public License
37
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38
 */
39
namespace Alixar\Base;
40
41
/**
42
 * 	\file       htdocs/core/class/html.form.class.php
43
 *  \ingroup    core
44
 * 	\brief      File of class with all html predefined components
45
 */
46
use Alixar\Helpers\Globals;
47
use Alixar\Helpers\DolUtils;
48
49
/**
50
 * 	Class to manage generation of HTML components
51
 * 	Only common components must be here.
52
 *
53
 *  TODO Merge all function load_cache_* and loadCache* (except load_cache_vatrates) into one generic function loadCacheTable
54
 */
55
class Form
56
{
57
    /**
58
     * @var DoliDB Database handler.
59
     */
60
    // public $db;
61
62
    /**
63
     * @var string Error code (or message)
64
     */
65
    public $error = '';
66
67
    /**
68
     * @var string[]    Array of error strings
69
     */
70
    public $errors = array();
71
    public $num;
72
    // Cache arrays
73
    public $cache_types_paiements = array();
74
    public $cache_conditions_paiements = array();
75
    public $cache_availability = array();
76
    public $cache_demand_reason = array();
77
    public $cache_types_fees = array();
78
    public $cache_vatrates = array();
79
80
    /**
81
     * Constructor
82
     *
83
     * @param		DoliDB		$db      Database handler
84
     */
85
    public function __construct()
86
    {
87
        // $this->db = $db;
88
    }
89
90
    /**
91
     * Output key field for an editable field
92
     *
93
     * @param   string	$text			Text of label or key to translate
94
     * @param   string	$htmlname		Name of select field ('edit' prefix will be added)
95
     * @param   string	$preselected    Value to show/edit (not used in this function)
96
     * @param	object	$object			Object
97
     * @param	boolean	$perm			Permission to allow button to edit parameter. Set it to 0 to have a not edited field.
98
     * @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]'...)
99
     * @param	string	$moreparam		More param to add on a href URL.
100
     * @param   int     $fieldrequired  1 if we want to show field as mandatory using the "fieldrequired" CSS.
101
     * @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 ' '
102
     * @param	string	$paramid		Key of parameter for id ('id', 'socid')
103
     * @return	string					HTML edit field
104
     */
105
    function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata = 'string', $moreparam = '', $fieldrequired = 0, $notabletag = 0, $paramid = 'id')
106
    {
107
        global $conf, $langs;
108
109
        $ret = '';
110
111
        // TODO change for compatibility
112
        if (!empty(Globals::$conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;/', $typeofdata)) {
113
            if (!empty($perm)) {
114
                $tmp = explode(':', $typeofdata);
115
                $ret .= '<div class="editkey_' . $tmp[0] . (!empty($tmp[1]) ? ' ' . $tmp[1] : '') . '" id="' . $htmlname . '">';
116
                if ($fieldrequired)
117
                    $ret .= '<span class="fieldrequired">';
118
                $ret .= $langs->trans($text);
119
                if ($fieldrequired)
120
                    $ret .= '</span>';
121
                $ret .= '</div>' . "\n";
122
            }
123
            else {
124
                if ($fieldrequired)
125
                    $ret .= '<span class="fieldrequired">';
126
                $ret .= $langs->trans($text);
127
                if ($fieldrequired)
128
                    $ret .= '</span>';
129
            }
130
        }
131
        else {
132
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
133
                $ret .= '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
134
            }
135
            if ($fieldrequired) {
136
                $ret .= '<span class="fieldrequired">';
137
            }
138
            $ret .= $langs->trans($text);
139
            if ($fieldrequired) {
140
                $ret .= '</span>';
141
            }
142
            if (!empty($notabletag)) {
143
                $ret .= ' ';
144
            }
145
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
146
                $ret .= '</td>';
147
            }
148
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
149
                $ret .= '<td align="right">';
150
            }
151
            if ($htmlname && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
152
                $ret .= '<a href="' . $_SERVER["PHP_SELF"] . '?action=edit' . $htmlname . '&amp;' . $paramid . '=' . $object->id . $moreparam . '">' . img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)) . '</a>';
153
            }
154
            if (!empty($notabletag) && $notabletag == 1) {
155
                $ret .= ' : ';
156
            }
157
            if (!empty($notabletag) && $notabletag == 3) {
158
                $ret .= ' ';
159
            }
160
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
161
                $ret .= '</td>';
162
            }
163
            if (empty($notabletag) && GETPOST('action', 'aZ09') != 'edit' . $htmlname && $perm) {
164
                $ret .= '</tr></table>';
165
            }
166
        }
167
168
        return $ret;
169
    }
170
171
    /**
172
     * Output value of a field for an editable field
173
     *
174
     * @param	string	$text			Text of label (not used in this function)
175
     * @param	string	$htmlname		Name of select field
176
     * @param	string	$value			Value to show/edit
177
     * @param	object	$object			Object
178
     * @param	boolean	$perm			Permission to allow button to edit parameter
179
     * @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'...)
180
     * @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
181
     * @param	object	$extObject		External object
182
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
183
     * @param	string	$moreparam		More param to add on the form action href URL
184
     * @param   int     $notabletag     Do no output table tags
185
     * @param	string	$formatfunc		Call a specific function to output field
186
     * @param	string	$paramid		Key of parameter for id ('id', 'socid')
187
     * @return  string					HTML edit field
188
     */
189
    function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 0, $formatfunc = '', $paramid = 'id')
190
    {
191
        global $conf, $langs, $db;
192
193
        $ret = '';
194
195
        // Check parameters
196
        if (empty($typeofdata))
197
            return 'ErrorBadParameter';
198
199
        // When option to edit inline is activated
200
        if (!empty(Globals::$conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;|datehourpicker/', $typeofdata)) { // TODO add jquery timepicker
201
            $ret .= $this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg);
202
        } else {
203
            if (GETPOST('action', 'aZ09') == 'edit' . $htmlname) {
204
                $ret .= "\n";
205
                $ret .= '<form method="post" action="' . $_SERVER["PHP_SELF"] . ($moreparam ? '?' . $moreparam : '') . '">';
206
                $ret .= '<input type="hidden" name="action" value="set' . $htmlname . '">';
207
                $ret .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
208
                $ret .= '<input type="hidden" name="' . $paramid . '" value="' . $object->id . '">';
209
                if (empty($notabletag))
210
                    $ret .= '<table class="nobordernopadding centpercent" cellpadding="0" cellspacing="0">';
211
                if (empty($notabletag))
212
                    $ret .= '<tr><td>';
213
                if (preg_match('/^(string|email)/', $typeofdata)) {
214
                    $tmp = explode(':', $typeofdata);
215
                    $ret .= '<input type="text" id="' . $htmlname . '" name="' . $htmlname . '" value="' . ($editvalue ? $editvalue : $value) . '"' . ($tmp[1] ? ' size="' . $tmp[1] . '"' : '') . '>';
216
                } else if (preg_match('/^(numeric|amount)/', $typeofdata)) {
217
                    $tmp = explode(':', $typeofdata);
218
                    $valuetoshow = price2num($editvalue ? $editvalue : $value);
219
                    $ret .= '<input type="text" id="' . $htmlname . '" name="' . $htmlname . '" value="' . ($valuetoshow != '' ? price($valuetoshow) : '') . '"' . ($tmp[1] ? ' size="' . $tmp[1] . '"' : '') . '>';
220
                } else if (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata)) {
221
                    $tmp = explode(':', $typeofdata);
222
                    $cols = $tmp[2];
223
                    $morealt = '';
224
                    if (preg_match('/%/', $cols)) {
225
                        $morealt = ' style="width: ' . $cols . '"';
226
                        $cols = '';
227
                    }
228
229
                    $valuetoshow = ($editvalue ? $editvalue : $value);
230
231
                    $ret .= '<textarea id="' . $htmlname . '" name="' . $htmlname . '" wrap="soft" rows="' . ($tmp[1] ? $tmp[1] : '20') . '"' . ($cols ? ' cols="' . $cols . '"' : 'class="quatrevingtpercent"') . $morealt . '">';
232
                    $ret .= dol_string_neverthesehtmltags($valuetoshow, array('textarea'));
233
                    $ret .= '</textarea>';
234
                } else if ($typeofdata == 'day' || $typeofdata == 'datepicker') {
235
                    $ret .= $this->selectDate($value, $htmlname, 0, 0, 1, 'form' . $htmlname, 1, 0);
236
                } else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') {
237
                    $ret .= $this->selectDate($value, $htmlname, 1, 1, 1, 'form' . $htmlname, 1, 0);
238
                } else if (preg_match('/^select;/', $typeofdata)) {
239
                    $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata));
240
                    foreach ($arraydata as $val) {
241
                        $tmp = explode(':', $val);
242
                        $arraylist[$tmp[0]] = $tmp[1];
243
                    }
244
                    $ret .= $this->selectarray($htmlname, $arraylist, $value);
245
                } else if (preg_match('/^ckeditor/', $typeofdata)) {
246
                    $tmp = explode(':', $typeofdata);  // Example: ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols
247
                    require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
248
                    $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'));
249
                    $ret .= $doleditor->Create(1);
250
                }
251
                if (empty($notabletag))
252
                    $ret .= '</td>';
253
254
                if (empty($notabletag))
255
                    $ret .= '<td align="left">';
256
                //else $ret.='<div class="clearboth"></div>';
257
                $ret .= '<input type="submit" class="button' . (empty($notabletag) ? '' : ' ') . '" name="modify" value="' . $langs->trans("Modify") . '">';
258
                if (preg_match('/ckeditor|textarea/', $typeofdata) && empty($notabletag))
259
                    $ret .= '<br>' . "\n";
260
                $ret .= '<input type="submit" class="button' . (empty($notabletag) ? '' : ' ') . '" name="cancel" value="' . $langs->trans("Cancel") . '">';
261
                if (empty($notabletag))
262
                    $ret .= '</td>';
263
264
                if (empty($notabletag))
265
                    $ret .= '</tr></table>' . "\n";
266
                $ret .= '</form>' . "\n";
267
            }
268
            else {
269
                if (preg_match('/^(email)/', $typeofdata))
270
                    $ret .= dol_print_email($value, 0, 0, 0, 0, 1);
271
                elseif (preg_match('/^(amount|numeric)/', $typeofdata))
272
                    $ret .= ($value != '' ? price($value, '', $langs, 0, -1, -1, Globals::$conf->currency) : '');
273
                elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata))
274
                    $ret .= dol_htmlentitiesbr($value);
275
                elseif ($typeofdata == 'day' || $typeofdata == 'datepicker')
276
                    $ret .= DolUtils::dol_print_date($value, 'day');
277
                elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
278
                    $ret .= DolUtils::dol_print_date($value, 'dayhour');
279
                else if (preg_match('/^select;/', $typeofdata)) {
280
                    $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata));
281
                    foreach ($arraydata as $val) {
282
                        $tmp = explode(':', $val);
283
                        $arraylist[$tmp[0]] = $tmp[1];
284
                    }
285
                    $ret .= $arraylist[$value];
286
                } else if (preg_match('/^ckeditor/', $typeofdata)) {
287
                    $tmpcontent = dol_htmlentitiesbr($value);
288
                    if (!empty(Globals::$conf->global->MAIN_DISABLE_NOTES_TAB)) {
289
                        $firstline = preg_replace('/<br>.*/', '', $tmpcontent);
290
                        $firstline = preg_replace('/[\n\r].*/', '', $firstline);
291
                        $tmpcontent = $firstline . ((strlen($firstline) != strlen($tmpcontent)) ? '...' : '');
292
                    }
293
                    $ret .= $tmpcontent;
294
                } else
295
                    $ret .= $value;
296
297
                if ($formatfunc && method_exists($object, $formatfunc)) {
298
                    $ret = $object->$formatfunc($ret);
299
                }
300
            }
301
        }
302
        return $ret;
303
    }
304
305
    /**
306
     * Output edit in place form
307
     *
308
     * @param	object	$object			Object
309
     * @param	string	$value			Value to show/edit
310
     * @param	string	$htmlname		DIV ID (field name)
311
     * @param	int		$condition		Condition to edit
312
     * @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')
313
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value
314
     * @param	object	$extObject		External object
315
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
316
     * @return	string   		      	HTML edit in place
317
     */
318
    private function editInPlace($object, $value, $htmlname, $condition, $inputType = 'textarea', $editvalue = null, $extObject = null, $custommsg = null)
319
    {
320
        global $conf;
321
322
        $out = '';
323
324
        // Check parameters
325
        if (preg_match('/^text/', $inputType))
326
            $value = dol_nl2br($value);
327
        else if (preg_match('/^numeric/', $inputType))
328
            $value = price($value);
329
        else if ($inputType == 'day' || $inputType == 'datepicker')
330
            $value = DolUtils::dol_print_date($value, 'day');
331
332
        if ($condition) {
333
            $element = false;
334
            $table_element = false;
335
            $fk_element = false;
336
            $loadmethod = false;
337
            $savemethod = false;
338
            $ext_element = false;
339
            $button_only = false;
340
            $inputOption = '';
341
342
            if (is_object($object)) {
343
                $element = $object->element;
344
                $table_element = $object->table_element;
345
                $fk_element = $object->id;
346
            }
347
348
            if (is_object($extObject)) {
349
                $ext_element = $extObject->element;
350
            }
351
352
            if (preg_match('/^(string|email|numeric)/', $inputType)) {
353
                $tmp = explode(':', $inputType);
354
                $inputType = $tmp[0];
355
                if (!empty($tmp[1]))
356
                    $inputOption = $tmp[1];
357
                if (!empty($tmp[2]))
358
                    $savemethod = $tmp[2];
359
                $out .= '<input id="width_' . $htmlname . '" value="' . $inputOption . '" type="hidden"/>' . "\n";
360
            }
361
            else if ((preg_match('/^day$/', $inputType)) || (preg_match('/^datepicker/', $inputType)) || (preg_match('/^datehourpicker/', $inputType))) {
362
                $tmp = explode(':', $inputType);
363
                $inputType = $tmp[0];
364
                if (!empty($tmp[1]))
365
                    $inputOption = $tmp[1];
366
                if (!empty($tmp[2]))
367
                    $savemethod = $tmp[2];
368
369
                $out .= '<input id="timestamp" type="hidden"/>' . "\n"; // Use for timestamp format
370
            }
371
            else if (preg_match('/^(select|autocomplete)/', $inputType)) {
372
                $tmp = explode(':', $inputType);
373
                $inputType = $tmp[0];
374
                $loadmethod = $tmp[1];
375
                if (!empty($tmp[2]))
376
                    $savemethod = $tmp[2];
377
                if (!empty($tmp[3]))
378
                    $button_only = true;
379
            }
380
            else if (preg_match('/^textarea/', $inputType)) {
381
                $tmp = explode(':', $inputType);
382
                $inputType = $tmp[0];
383
                $rows = (empty($tmp[1]) ? '8' : $tmp[1]);
384
                $cols = (empty($tmp[2]) ? '80' : $tmp[2]);
385
            } else if (preg_match('/^ckeditor/', $inputType)) {
386
                $tmp = explode(':', $inputType);
387
                $inputType = $tmp[0];
388
                $toolbar = $tmp[1];
389
                if (!empty($tmp[2]))
390
                    $width = $tmp[2];
391
                if (!empty($tmp[3]))
392
                    $heigth = $tmp[3];
393
                if (!empty($tmp[4]))
394
                    $savemethod = $tmp[4];
395
396
                if (!empty(Globals::$conf->fckeditor->enabled)) {
397
                    $out .= '<input id="ckeditor_toolbar" value="' . $toolbar . '" type="hidden"/>' . "\n";
398
                } else {
399
                    $inputType = 'textarea';
400
                }
401
            }
402
403
            $out .= '<input id="element_' . $htmlname . '" value="' . $element . '" type="hidden"/>' . "\n";
404
            $out .= '<input id="table_element_' . $htmlname . '" value="' . $table_element . '" type="hidden"/>' . "\n";
405
            $out .= '<input id="fk_element_' . $htmlname . '" value="' . $fk_element . '" type="hidden"/>' . "\n";
406
            $out .= '<input id="loadmethod_' . $htmlname . '" value="' . $loadmethod . '" type="hidden"/>' . "\n";
407
            if (!empty($savemethod))
408
                $out .= '<input id="savemethod_' . $htmlname . '" value="' . $savemethod . '" type="hidden"/>' . "\n";
409
            if (!empty($ext_element))
410
                $out .= '<input id="ext_element_' . $htmlname . '" value="' . $ext_element . '" type="hidden"/>' . "\n";
411
            if (!empty($custommsg)) {
412
                if (is_array($custommsg)) {
413
                    if (!empty($custommsg['success']))
414
                        $out .= '<input id="successmsg_' . $htmlname . '" value="' . $custommsg['success'] . '" type="hidden"/>' . "\n";
415
                    if (!empty($custommsg['error']))
416
                        $out .= '<input id="errormsg_' . $htmlname . '" value="' . $custommsg['error'] . '" type="hidden"/>' . "\n";
417
                } else
418
                    $out .= '<input id="successmsg_' . $htmlname . '" value="' . $custommsg . '" type="hidden"/>' . "\n";
419
            }
420
            if ($inputType == 'textarea') {
421
                $out .= '<input id="textarea_' . $htmlname . '_rows" value="' . $rows . '" type="hidden"/>' . "\n";
422
                $out .= '<input id="textarea_' . $htmlname . '_cols" value="' . $cols . '" type="hidden"/>' . "\n";
423
            }
424
            $out .= '<span id="viewval_' . $htmlname . '" class="viewval_' . $inputType . ($button_only ? ' inactive' : ' active') . '">' . $value . '</span>' . "\n";
425
            $out .= '<span id="editval_' . $htmlname . '" class="editval_' . $inputType . ($button_only ? ' inactive' : ' active') . ' hideobject">' . (!empty($editvalue) ? $editvalue : $value) . '</span>' . "\n";
426
        } else {
427
            $out = $value;
428
        }
429
430
        return $out;
431
    }
432
433
    /**
434
     * 	Show a text and picto with tooltip on text or picto.
435
     *  Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip
436
     *
437
     * 	@param	string		$text				Text to show
438
     * 	@param	string		$htmltext			HTML content of tooltip. Must be HTML/UTF8 encoded.
439
     * 	@param	int			$tooltipon			1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2
440
     * 	@param	int			$direction			-1=image is before, 0=no image, 1=image is after
441
     * 	@param	string		$img				Html code for image (use img_xxx() function to get it)
442
     * 	@param	string		$extracss			Add a CSS style to td tags
443
     * 	@param	int			$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
444
     * 	@param	string		$incbefore			Include code before the text
445
     * 	@param	int			$noencodehtmltext	Do not encode into html entity the htmltext
446
     *  @param  string      $tooltiptrigger		''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
447
     *  @param	int			$forcenowrap		Force no wrap between text and picto (works with notabs=2 only)
448
     * 	@return	string							Code html du tooltip (texte+picto)
449
     * 	@see	Use function textwithpicto if you can.
450
     *  TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip
451
     */
452
    function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0)
453
    {
454
        global $conf;
455
456
        if ($incbefore) {
457
            $text = $incbefore . $text;
458
        }
459
        if (!$htmltext) {
460
            return $text;
461
        }
462
463
        $tag = 'td';
464
        if ($notabs == 2) {
465
            $tag = 'div';
466
        }
467
        if ($notabs == 3) {
468
            $tag = 'span';
469
        }
470
        // Sanitize tooltip
471
        $htmltext = str_replace("\\", "\\\\", $htmltext);
472
        $htmltext = str_replace("\r", "", $htmltext);
473
        $htmltext = str_replace("\n", "", $htmltext);
474
475
        $extrastyle = '';
476
        if ($direction < 0) {
477
            $extracss = ($extracss ? $extracss . ' ' : '') . 'inline-block';
478
            $extrastyle = 'padding: 0px; padding-left: 3px !important;';
479
        }
480
        if ($direction > 0) {
481
            $extracss = ($extracss ? $extracss . ' ' : '') . 'inline-block';
482
            $extrastyle = 'padding: 0px; padding-right: 3px !important;';
483
        }
484
485
        $classfortooltip = 'classfortooltip';
486
487
        $s = '';
488
        $textfordialog = '';
489
490
        if ($tooltiptrigger == '') {
491
            $htmltext = str_replace('"', "&quot;", $htmltext);
492
        } else {
493
            $classfortooltip = 'classfortooltiponclick';
494
            $textfordialog .= '<div style="display: none;" id="idfortooltiponclick_' . $tooltiptrigger . '" class="classfortooltiponclicktext">' . $htmltext . '</div>';
495
        }
496
        if ($tooltipon == 2 || $tooltipon == 3) {
497
            $paramfortooltipimg = ' class="' . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '"';
498
            if ($tooltiptrigger == '') {
499
                $paramfortooltipimg .= ' title="' . ($noencodehtmltext ? $htmltext : DolUtils::dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on img tag to store tooltip
500
            } else {
501
                $paramfortooltipimg .= ' dolid="' . $tooltiptrigger . '"';
502
            }
503
        } else {
504
            $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag
505
        }
506
        if ($tooltipon == 1 || $tooltipon == 3) {
507
            $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" ';
508
            if ($tooltiptrigger == '') {
509
                $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : DolUtils::dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on td tag to store tooltip
510
            } else {
511
                $paramfortooltiptd .= ' dolid="' . $tooltiptrigger . '"';
512
            }
513
        } else {
514
            $paramfortooltiptd = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag
515
        }
516
        if (empty($notabs)) {
517
            $s .= '<table class="nobordernopadding" summary=""><tr style="height: auto;">';
518
        } elseif ($notabs == 2) {
519
            $s .= '<div class="inline-block' . ($forcenowrap ? ' nowrap' : '') . '">';
520
        }
521
        // Define value if value is before
522
        if ($direction < 0) {
523
            $s .= '<' . $tag . $paramfortooltipimg;
524
            if ($tag == 'td') {
525
                $s .= ' valign="top" width="14"';
526
            }
527
            $s .= '>' . $textfordialog . $img . '</' . $tag . '>';
528
        }
529
        // Use another method to help avoid having a space in value in order to use this value with jquery
530
        // Define label
531
        if ((string) $text != '') {
532
            $s .= '<' . $tag . $paramfortooltiptd . '>' . $text . '</' . $tag . '>';
533
        }
534
        // Define value if value is after
535
        if ($direction > 0) {
536
            $s .= '<' . $tag . $paramfortooltipimg;
537
            if ($tag == 'td') {
538
                $s .= ' valign="middle" width="14"';
539
            }
540
            $s .= '>' . $textfordialog . $img . '</' . $tag . '>';
541
        }
542
        if (empty($notabs)) {
543
            $s .= '</tr></table>';
544
        } elseif ($notabs == 2) {
545
            $s .= '</div>';
546
        }
547
548
        return $s;
549
    }
550
551
    /**
552
     * 	Show a text with a picto and a tooltip on picto
553
     *
554
     * 	@param	string	$text				Text to show
555
     * 	@param  string	$htmltext	     	Content of tooltip
556
     * 	@param	int		$direction			1=Icon is after text, -1=Icon is before text, 0=no icon
557
     * 	@param	string	$type				Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath
558
     *  @param  string	$extracss           Add a CSS style to td, div or span tag
559
     *  @param  int		$noencodehtmltext   Do not encode into html entity the htmltext
560
     *  @param	int		$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
561
     *  @param  string  $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
562
     *  @param	int		$forcenowrap		Force no wrap between text and picto (works with notabs=2 only)
563
     * 	@return	string						HTML code of text, picto, tooltip
564
     */
565
    function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger = '', $forcenowrap = 0)
566
    {
567
        global $conf, $langs;
568
569
        $alt = '';
570
        if ($tooltiptrigger)
571
            $alt = $langs->transnoentitiesnoconv("ClickToShowHelp");
572
573
        //For backwards compatibility
574
        if ($type == '0')
575
            $type = 'info';
576
        elseif ($type == '1')
577
            $type = 'help';
578
579
        // If info or help with no javascript, show only text
580
        if (empty(Globals::$conf->use_javascript_ajax)) {
581
            if ($type == 'info' || $type == 'help')
582
                return $text;
583
            else {
584
                $alt = $htmltext;
585
                $htmltext = '';
586
            }
587
        }
588
589
        // If info or help with smartphone, show only text (tooltip hover can't works)
590
        if (!empty(Globals::$conf->dol_no_mouse_hover) && empty($tooltiptrigger)) {
591
            if ($type == 'info' || $type == 'help')
592
                return $text;
593
        }
594
        // If info or help with smartphone, show only text (tooltip on lick does not works with dialog on smaprtphone)
595
        if (!empty(Globals::$conf->dol_no_mouse_hover) && !empty($tooltiptrigger)) {
596
            if ($type == 'info' || $type == 'help')
597
                return $text;
598
        }
599
600
        if ($type == 'info')
601
            $img = img_help(0, $alt);
602
        elseif ($type == 'help')
603
            $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt);
604
        elseif ($type == 'superadmin')
605
            $img = img_picto($alt, 'redstar');
606
        elseif ($type == 'admin')
607
            $img = img_picto($alt, 'star');
608
        elseif ($type == 'warning')
609
            $img = img_warning($alt);
610
        else
611
            $img = img_picto($alt, $type);
612
613
        return $this->textwithtooltip($text, $htmltext, (($tooltiptrigger && !$img) ? 3 : 2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger, $forcenowrap);
614
    }
615
616
    /**
617
     * Generate select HTML to choose massaction
618
     *
619
     * @param	string	$selected		Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default.
620
     * @param	int		$arrayofaction	array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action.
621
     * @param   int     $alwaysvisible  1=select button always visible
622
     * @return	string					Select list
623
     */
624
    function selectMassAction($selected, $arrayofaction, $alwaysvisible = 0)
625
    {
626
        global $conf, $langs, $hookmanager;
627
628
        if (count($arrayofaction) == 0)
629
            return;
630
631
        $disabled = 0;
632
        $ret = '<div class="centpercent center">';
633
        $ret .= '<select class="flat' . (empty(Globals::$conf->use_javascript_ajax) ? '' : ' hideobject') . ' massaction massactionselect" name="massaction"' . ($disabled ? ' disabled="disabled"' : '') . '>';
634
635
        // 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.
636
        $parameters = array();
637
        $reshook = $hookmanager->executeHooks('addMoreMassActions', $parameters);    // Note that $action and $object may have been modified by hook
638
        if (empty($reshook)) {
639
            $ret .= '<option value="0"' . ($disabled ? ' disabled="disabled"' : '') . '>-- ' . $langs->trans("SelectAction") . ' --</option>';
640
            foreach ($arrayofaction as $code => $label) {
641
                $ret .= '<option value="' . $code . '"' . ($disabled ? ' disabled="disabled"' : '') . '>' . $label . '</option>';
642
            }
643
        }
644
        $ret .= $hookmanager->resPrint;
645
646
        $ret .= '</select>';
647
        // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button
648
        $ret .= '<input type="submit" name="confirmmassactioninvisible" style="display: none" tabindex="-1">'; // Hidden button BEFORE so it is the one used when we submit with ENTER.
649
        $ret .= '<input type="submit" disabled name="confirmmassaction" class="button' . (empty(Globals::$conf->use_javascript_ajax) ? '' : ' hideobject') . ' massaction massactionconfirmed" value="' . DolUtils::dol_escape_htmltag($langs->trans("Confirm")) . '">';
650
        $ret .= '</div>';
651
652
        if (!empty(Globals::$conf->use_javascript_ajax)) {
653
            $ret .= '<!-- JS CODE TO ENABLE mass action select -->
654
    		<script type="text/javascript">
655
        		function initCheckForSelect(mode)	/* mode is 0 during init of page or click all, 1 when we click on 1 checkbox */
656
        		{
657
        			atleastoneselected=0;
658
    	    		jQuery(".checkforselect").each(function( index ) {
659
    	  				/* console.log( index + ": " + $( this ).text() ); */
660
    	  				if ($(this).is(\':checked\')) atleastoneselected++;
661
    	  			});
662
					console.log("initCheckForSelect mode="+mode+" atleastoneselected="+atleastoneselected);
663
    	  			if (atleastoneselected || ' . $alwaysvisible . ')
664
    	  			{
665
    	  				jQuery(".massaction").show();
666
        			    ' . ($selected ? 'if (atleastoneselected) { jQuery(".massactionselect").val("' . $selected . '"); jQuery(".massactionconfirmed").prop(\'disabled\', false); }' : '') . '
667
        			    ' . ($selected ? 'if (! atleastoneselected) { jQuery(".massactionselect").val("0"); jQuery(".massactionconfirmed").prop(\'disabled\', true); } ' : '') . '
668
    	  			}
669
    	  			else
670
    	  			{
671
    	  				jQuery(".massaction").hide();
672
    	            }
673
        		}
674
675
        	jQuery(document).ready(function () {
676
        		initCheckForSelect(0);
677
        		jQuery(".checkforselect").click(function() {
678
        			initCheckForSelect(1);
679
    	  		});
680
    	  		jQuery(".massactionselect").change(function() {
681
        			var massaction = $( this ).val();
682
        			var urlform = $( this ).closest("form").attr("action").replace("#show_files","");
683
        			if (massaction == "builddoc")
684
                    {
685
                        urlform = urlform + "#show_files";
686
    	            }
687
        			$( this ).closest("form").attr("action", urlform);
688
                    console.log("we select a mass action "+massaction+" - "+urlform);
689
        	        /* Warning: if you set submit button to disabled, post using Enter will no more work if there is no other button */
690
        			if ($(this).val() != \'0\')
691
    	  			{
692
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', false);
693
    	  			}
694
    	  			else
695
    	  			{
696
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', true);
697
    	  			}
698
    	        });
699
        	});
700
    		</script>
701
        	';
702
        }
703
704
        return $ret;
705
    }
706
707
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
708
    /**
709
     *  Return combo list of activated countries, into language of user
710
     *
711
     *  @param	string	$selected       	Id or Code or Label of preselected country
712
     *  @param  string	$htmlname       	Name of html select object
713
     *  @param  string	$htmloption     	Options html on select object
714
     *  @param	integer	$maxlength			Max length for labels (0=no limit)
715
     *  @param	string	$morecss			More css class
716
     *  @param	string	$usecodeaskey		''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key
717
     *  @param	int		$showempty			Show empty choice
718
     *  @param	int		$disablefavorites	1=Disable favorites,
719
     *  @param	int		$addspecialentries	1=Add dedicated entries for group of countries (like 'European Economic Community', ...)
720
     *  @return string           			HTML string with select
721
     */
722
    function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0)
723
    {
724
        // phpcs:enable
725
        global $conf, $langs, $mysoc;
726
727
        $langs->load("dict");
728
729
        $out = '';
730
        $countryArray = array();
731
        $favorite = array();
732
        $label = array();
733
        $atleastonefavorite = 0;
734
735
        $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite";
736
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_country";
737
        $sql .= " WHERE active > 0";
738
        //$sql.= " ORDER BY code ASC";
739
740
        dol_syslog(get_class($this) . "::select_country", LOG_DEBUG);
741
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
742
        if ($resql) {
743
            $out .= '<select id="select' . $htmlname . '" class="flat maxwidth200onsmartphone selectcountry' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" ' . $htmloption . '>';
744
            $num = $this->db->num_rows($resql);
745
            $i = 0;
746
            if ($num) {
747
                $foundselected = false;
748
749
                while ($i < $num) {
750
                    $obj = $this->db->fetch_object($resql);
751
                    $countryArray[$i]['rowid'] = $obj->rowid;
752
                    $countryArray[$i]['code_iso'] = $obj->code_iso;
753
                    $countryArray[$i]['code_iso3'] = $obj->code_iso3;
754
                    $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 : ''));
755
                    $countryArray[$i]['favorite'] = $obj->favorite;
756
                    $favorite[$i] = $obj->favorite;
757
                    $label[$i] = dol_string_unaccent($countryArray[$i]['label']);
758
                    $i++;
759
                }
760
761
                if (empty($disablefavorites))
762
                    array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray);
763
                else
764
                    $countryArray = dol_sort_array($countryArray, 'label');
765
766
                if ($showempty) {
767
                    $out .= '<option value="">&nbsp;</option>' . "\n";
768
                }
769
770
                if ($addspecialentries) { // Add dedicated entries for groups of countries
771
                    //if ($showempty) $out.= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
772
                    $out .= '<option value="special_allnotme"' . ($selected == 'special_allnotme' ? ' selected' : '') . '>' . $langs->trans("CountriesExceptMe", $langs->transnoentitiesnoconv("Country" . $mysoc->country_code)) . '</option>';
773
                    $out .= '<option value="special_eec"' . ($selected == 'special_eec' ? ' selected' : '') . '>' . $langs->trans("CountriesInEEC") . '</option>';
774
                    if ($mysoc->isInEEC())
775
                        $out .= '<option value="special_eecnotme"' . ($selected == 'special_eecnotme' ? ' selected' : '') . '>' . $langs->trans("CountriesInEECExceptMe", $langs->transnoentitiesnoconv("Country" . $mysoc->country_code)) . '</option>';
776
                    $out .= '<option value="special_noteec"' . ($selected == 'special_noteec' ? ' selected' : '') . '>' . $langs->trans("CountriesNotInEEC") . '</option>';
777
                    $out .= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
778
                }
779
780
                foreach ($countryArray as $row) {
781
                    //if (empty($showempty) && empty($row['rowid'])) continue;
782
                    if (empty($row['rowid'])) {
783
                        continue;
784
                    }
785
786
                    if (empty($disablefavorites) && $row['favorite'] && $row['code_iso'])
787
                        $atleastonefavorite++;
788
                    if (empty($row['favorite']) && $atleastonefavorite) {
789
                        $atleastonefavorite = 0;
790
                        $out .= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
791
                    }
792
                    if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label'])) {
793
                        $foundselected = true;
794
                        $out .= '<option value="' . ($usecodeaskey ? ($usecodeaskey == 'code2' ? $row['code_iso'] : $row['code_iso3']) : $row['rowid']) . '" selected>';
795
                    } else {
796
                        $out .= '<option value="' . ($usecodeaskey ? ($usecodeaskey == 'code2' ? $row['code_iso'] : $row['code_iso3']) : $row['rowid']) . '">';
797
                    }
798
                    if ($row['label'])
799
                        $out .= dol_trunc($row['label'], $maxlength, 'middle');
800
                    else
801
                        $out .= '&nbsp;';
802
                    if ($row['code_iso'])
803
                        $out .= ' (' . $row['code_iso'] . ')';
804
                    $out .= '</option>';
805
                }
806
            }
807
            $out .= '</select>';
808
        }
809
        else {
810
            DolUtils::dol_print_error($this->db);
811
        }
812
813
        // Make select dynamic
814
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
815
        $out .= ajax_combobox('select' . $htmlname);
816
817
        return $out;
818
    }
819
820
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
821
    /**
822
     *  Return select list of incoterms
823
     *
824
     *  @param	string	$selected       		Id or Code of preselected incoterm
825
     *  @param	string	$location_incoterms     Value of input location
826
     *  @param	string	$page       			Defined the form action
827
     *  @param  string	$htmlname       		Name of html select object
828
     *  @param  string	$htmloption     		Options html on select object
829
     * 	@param	int		$forcecombo				Force to load all values and output a standard combobox (with no beautification)
830
     *  @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')))
831
     *  @return string           				HTML string with select and input
832
     */
833
    function select_incoterms($selected = '', $location_incoterms = '', $page = '', $htmlname = 'incoterm_id', $htmloption = '', $forcecombo = 1, $events = array())
834
    {
835
        // phpcs:enable
836
        global $conf, $langs;
837
838
        $langs->load("dict");
839
840
        $out = '';
841
        $incotermArray = array();
842
843
        $sql = "SELECT rowid, code";
844
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_incoterms";
845
        $sql .= " WHERE active > 0";
846
        $sql .= " ORDER BY code ASC";
847
848
        dol_syslog(get_class($this) . "::select_incoterm", LOG_DEBUG);
849
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
850
        if ($resql) {
851
            if (Globals::$conf->use_javascript_ajax && !$forcecombo) {
852
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
853
                $out .= ajax_combobox($htmlname, $events);
854
            }
855
856
            if (!empty($page)) {
857
                $out .= '<form method="post" action="' . $page . '">';
858
                $out .= '<input type="hidden" name="action" value="set_incoterms">';
859
                $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
860
            }
861
862
            $out .= '<select id="' . $htmlname . '" class="flat selectincoterm minwidth100imp noenlargeonsmartphone" name="' . $htmlname . '" ' . $htmloption . '>';
863
            $out .= '<option value="0">&nbsp;</option>';
864
            $num = $this->db->num_rows($resql);
865
            $i = 0;
866
            if ($num) {
867
                $foundselected = false;
868
869
                while ($i < $num) {
870
                    $obj = $this->db->fetch_object($resql);
871
                    $incotermArray[$i]['rowid'] = $obj->rowid;
872
                    $incotermArray[$i]['code'] = $obj->code;
873
                    $i++;
874
                }
875
876
                foreach ($incotermArray as $row) {
877
                    if ($selected && ($selected == $row['rowid'] || $selected == $row['code'])) {
878
                        $out .= '<option value="' . $row['rowid'] . '" selected>';
879
                    } else {
880
                        $out .= '<option value="' . $row['rowid'] . '">';
881
                    }
882
883
                    if ($row['code'])
884
                        $out .= $row['code'];
885
886
                    $out .= '</option>';
887
                }
888
            }
889
            $out .= '</select>';
890
891
            $out .= '<input id="location_incoterms" class="maxwidth100onsmartphone" name="location_incoterms" value="' . $location_incoterms . '">';
892
893
            if (!empty($page)) {
894
                $out .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '"></form>';
895
            }
896
        } else {
897
            DolUtils::dol_print_error($this->db);
898
        }
899
900
        return $out;
901
    }
902
903
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
904
    /**
905
     * 	Return list of types of lines (product or service)
906
     * 	Example: 0=product, 1=service, 9=other (for external module)
907
     *
908
     * 	@param  string	$selected       Preselected type
909
     * 	@param  string	$htmlname       Name of field in html form
910
     * 	@param	int		$showempty		Add an empty field
911
     * 	@param	int		$hidetext		Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
912
     * 	@param	integer	$forceall		1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service')
913
     *  @return	void
914
     */
915
    function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0)
916
    {
917
        // phpcs:enable
918
        global $db, $langs, $user, $conf;
919
920
        // If product & services are enabled or both disabled.
921
        if ($forceall == 1 || (empty($forceall) && !empty(Globals::$conf->product->enabled) && !empty(Globals::$conf->service->enabled)) || (empty($forceall) && empty(Globals::$conf->product->enabled) && empty(Globals::$conf->service->enabled))) {
922
            if (empty($hidetext))
923
                print $langs->trans("Type") . ': ';
924
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
925
            if ($showempty) {
926
                print '<option value="-1"';
927
                if ($selected == -1)
928
                    print ' selected';
929
                print '>&nbsp;</option>';
930
            }
931
932
            print '<option value="0"';
933
            if (0 == $selected)
934
                print ' selected';
935
            print '>' . $langs->trans("Product");
936
937
            print '<option value="1"';
938
            if (1 == $selected)
939
                print ' selected';
940
            print '>' . $langs->trans("Service");
941
942
            print '</select>';
943
            //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
944
        }
945
        if ((empty($forceall) && empty(Globals::$conf->product->enabled) && !empty(Globals::$conf->service->enabled)) || $forceall == 3) {
946
            print $langs->trans("Service");
947
            print '<input type="hidden" name="' . $htmlname . '" value="1">';
948
        }
949
        if ((empty($forceall) && !empty(Globals::$conf->product->enabled) && empty(Globals::$conf->service->enabled)) || $forceall == 2) {
950
            print $langs->trans("Product");
951
            print '<input type="hidden" name="' . $htmlname . '" value="0">';
952
        }
953
        if ($forceall < 0) { // This should happened only for contracts when both predefined product and service are disabled.
954
            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
955
        }
956
    }
957
958
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
959
    /**
960
     * 	Load into cache cache_types_fees, array of types of fees
961
     *
962
     * 	@return     int             Nb of lines loaded, <0 if KO
963
     */
964
    function load_cache_types_fees()
965
    {
966
        // phpcs:enable
967
        global $langs;
968
969
        $num = count($this->cache_types_fees);
970
        if ($num > 0)
971
            return 0;    // Cache already loaded
972
973
        dol_syslog(__METHOD__, LOG_DEBUG);
974
975
        $langs->load("trips");
976
977
        $sql = "SELECT c.code, c.label";
978
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_type_fees as c";
979
        $sql .= " WHERE active > 0";
980
981
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
982
        if ($resql) {
983
            $num = $this->db->num_rows($resql);
984
            $i = 0;
985
986
            while ($i < $num) {
987
                $obj = $this->db->fetch_object($resql);
988
989
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
990
                $label = ($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
991
                $this->cache_types_fees[$obj->code] = $label;
992
                $i++;
993
            }
994
995
            asort($this->cache_types_fees);
996
997
            return $num;
998
        } else {
999
            DolUtils::dol_print_error($this->db);
1000
            return -1;
1001
        }
1002
    }
1003
1004
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1005
    /**
1006
     * 	Return list of types of notes
1007
     *
1008
     * 	@param	string		$selected		Preselected type
1009
     * 	@param  string		$htmlname		Name of field in form
1010
     * 	@param	int			$showempty		Add an empty field
1011
     * 	@return	void
1012
     */
1013
    function select_type_fees($selected = '', $htmlname = 'type', $showempty = 0)
1014
    {
1015
        // phpcs:enable
1016
        global $user, $langs;
1017
1018
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
1019
1020
        $this->load_cache_types_fees();
1021
1022
        print '<select id="select_' . $htmlname . '" class="flat" name="' . $htmlname . '">';
1023
        if ($showempty) {
1024
            print '<option value="-1"';
1025
            if ($selected == -1)
1026
                print ' selected';
1027
            print '>&nbsp;</option>';
1028
        }
1029
1030
        foreach ($this->cache_types_fees as $key => $value) {
1031
            print '<option value="' . $key . '"';
1032
            if ($key == $selected)
1033
                print ' selected';
1034
            print '>';
1035
            print $value;
1036
            print '</option>';
1037
        }
1038
1039
        print '</select>';
1040
        if ($user->admin)
1041
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1042
    }
1043
1044
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1045
    /**
1046
     *  Return HTML code to select a company.
1047
     *
1048
     *  @param		int			$selected				Preselected products
1049
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1050
     *  @param		int			$filter					Filter on thirdparty
1051
     *  @param		int			$limit					Limit on number of returned lines
1052
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1053
     * 	@param		int			$forcecombo				Force to load all values and output a standard combobox (with no beautification)
1054
     *  @return		string								Return select box for thirdparty.
1055
     *  @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)
1056
     */
1057
    function select_thirdparty($selected = '', $htmlname = 'socid', $filter = '', $limit = 20, $ajaxoptions = array(), $forcecombo = 0)
1058
    {
1059
        // phpcs:enable
1060
        return $this->select_thirdparty_list($selected, $htmlname, $filter, 1, 0, $forcecombo, array(), '', 0, $limit);
1061
    }
1062
1063
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1064
    /**
1065
     *  Output html form to select a third party
1066
     *
1067
     * 	@param	string	$selected       		Preselected type
1068
     * 	@param  string	$htmlname       		Name of field in form
1069
     *  @param  string	$filter         		optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
1070
     * 	@param	string	$showempty				Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
1071
     * 	@param	int		$showtype				Show third party type in combolist (customer, prospect or supplier)
1072
     * 	@param	int		$forcecombo				Force to load all values and output a standard combobox (with no beautification)
1073
     *  @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')))
1074
     * 	@param	int		$limit					Maximum number of elements
1075
     *  @param	string	$morecss				Add more css styles to the SELECT component
1076
     * 	@param  string	$moreparam      		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1077
     * 	@param	string	$selected_input_value	Value of preselected input text (for use with ajax)
1078
     *  @param	int		$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1079
     *  @param	array	$ajaxoptions			Options for ajax_autocompleter
1080
     * 	@param  bool	$multiple				add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
1081
     * 	@return	string							HTML string with select box for thirdparty.
1082
     */
1083
    function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false)
1084
    {
1085
        // phpcs:enable
1086
        global $conf, $user, $langs;
1087
1088
        $out = '';
1089
1090
        if (!empty(Globals::$conf->use_javascript_ajax) && !empty(Globals::$conf->global->COMPANY_USE_SEARCH_TO_SELECT) && !$forcecombo) {
1091
            // No immediate load of all database
1092
            $placeholder = '';
1093
            if ($selected && empty($selected_input_value)) {
1094
                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
1095
                $societetmp = new Societe($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1096
                $societetmp->fetch($selected);
1097
                $selected_input_value = $societetmp->name;
1098
                unset($societetmp);
1099
            }
1100
            // mode 1
1101
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&filter=' . $filter . ($showtype ? '&showtype=' . $showtype : '');
1102
            $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/societe/ajax/company.php', $urloption, Globals::$conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1103
            $out .= '<style type="text/css">.ui-autocomplete { z-index: 250; }</style>';
1104
            if (empty($hidelabel))
1105
                print $langs->trans("RefOrLabel") . ' : ';
1106
            else if ($hidelabel > 1) {
1107
                $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
1108
                if ($hidelabel == 2) {
1109
                    $out .= img_picto($langs->trans("Search"), 'search');
1110
                }
1111
            }
1112
            $out .= '<input type="text" class="' . $morecss . '" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (!empty(Globals::$conf->global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '') . ' />';
1113
            if ($hidelabel == 3) {
1114
                $out .= img_picto($langs->trans("Search"), 'search');
1115
            }
1116
        } else {
1117
            // Immediate load of all database
1118
            $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple);
1119
        }
1120
1121
        return $out;
1122
    }
1123
1124
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1125
    /**
1126
     *  Output html form to select a third party.
1127
     *  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.
1128
     *
1129
     * 	@param	string	$selected       Preselected type
1130
     * 	@param  string	$htmlname       Name of field in form
1131
     *  @param  string	$filter         Optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)')
1132
     * 	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
1133
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
1134
     * 	@param	int		$forcecombo		Force to use standard HTML select component without beautification
1135
     *  @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')))
1136
     *  @param	string	$filterkey		Filter on key value
1137
     *  @param	int		$outputmode		0=HTML select string, 1=Array
1138
     *  @param	int		$limit			Limit number of answers
1139
     *  @param	string	$morecss		Add more css styles to the SELECT component
1140
     * 	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1141
     * 	@param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
1142
     * 	@return	string					HTML string with
1143
     */
1144
    function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false)
1145
    {
1146
        // phpcs:enable
1147
        global $conf, $user, $langs;
1148
1149
        $out = '';
1150
        $num = 0;
1151
        $outarray = array();
1152
1153
        if ($selected === '')
1154
            $selected = array();
1155
        else if (!is_array($selected))
1156
            $selected = array($selected);
1157
1158
        // Clean $filter that may contains sql conditions so sql code
1159
        if (function_exists('testSqlAndScriptInject')) {
1160
            if (testSqlAndScriptInject($filter, 3) > 0) {
1161
                $filter = '';
1162
            }
1163
        }
1164
1165
        // On recherche les societes
1166
        $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
1167
1168
        if (Globals::$conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1169
            $sql .= " ,s.address, s.zip, s.town";
1170
            $sql .= " , dictp.code as country_code";
1171
        }
1172
1173
        $sql .= " FROM (" . MAIN_DB_PREFIX . "societe as s";
1174
        if (!$user->rights->societe->client->voir && !$user->socid)
1175
            $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
1176
        $sql .= " )";
1177
        if (Globals::$conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1178
            $sql .= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "c_country as dictp ON dictp.rowid=s.fk_pays";
1179
        }
1180
        $sql .= " WHERE s.entity IN (" . getEntity('societe') . ")";
1181
        if (!empty($user->socid))
1182
            $sql .= " AND s.rowid = " . $user->socid;
1183
        if ($filter)
1184
            $sql .= " AND (" . $filter . ")";
1185
        if (!$user->rights->societe->client->voir && !$user->socid)
1186
            $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id;
1187
        if (!empty(Globals::$conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX))
1188
            $sql .= " AND s.status <> 0";
1189
        // Add criteria
1190
        if ($filterkey && $filterkey != '') {
1191
            $sql .= " AND (";
1192
            $prefix = empty(Globals::$conf->global->COMPANY_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on
1193
            // For natural search
1194
            $scrit = explode(' ', $filterkey);
1195
            $i = 0;
1196
            if (count($scrit) > 1)
1197
                $sql .= "(";
1198
            foreach ($scrit as $crit) {
1199
                if ($i > 0)
1200
                    $sql .= " AND ";
1201
                $sql .= "(s.nom LIKE '" . $this->db->escape($prefix . $crit) . "%')";
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1202
                $i++;
1203
            }
1204
            if (count($scrit) > 1)
1205
                $sql .= ")";
1206
            if (!empty(Globals::$conf->barcode->enabled)) {
1207
                $sql .= " OR s.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
1208
            }
1209
            $sql .= " OR s.code_client LIKE '" . $this->db->escape($prefix . $filterkey) . "%' OR s.code_fournisseur LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
1210
            $sql .= ")";
1211
        }
1212
        $sql .= $this->db->order("nom", "ASC");
1213
        $sql .= $this->db->plimit($limit, 0);
1214
1215
        // Build output string
1216
        dol_syslog(get_class($this) . "::select_thirdparty_list", LOG_DEBUG);
1217
        $resql = $this->db->query($sql);
1218
        if ($resql) {
1219
            if (!$forcecombo) {
1220
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1221
                $out .= ajax_combobox($htmlname, $events, Globals::$conf->global->COMPANY_USE_SEARCH_TO_SELECT);
1222
            }
1223
1224
            // Construct $out and $outarray
1225
            $out .= '<select id="' . $htmlname . '" class="flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($moreparam ? ' ' . $moreparam : '') . ' name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . '>' . "\n";
1226
1227
            $textifempty = '';
1228
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1229
            //if (! empty(Globals::$conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1230
            if (!empty(Globals::$conf->global->COMPANY_USE_SEARCH_TO_SELECT)) {
1231
                if ($showempty && !is_numeric($showempty))
1232
                    $textifempty = $langs->trans($showempty);
1233
                else
1234
                    $textifempty .= $langs->trans("All");
1235
            }
1236
            if ($showempty)
1237
                $out .= '<option value="-1">' . $textifempty . '</option>' . "\n";
1238
1239
            $num = $this->db->num_rows($resql);
1240
            $i = 0;
1241
            if ($num) {
1242
                while ($i < $num) {
1243
                    $obj = $this->db->fetch_object($resql);
1244
                    $label = '';
1245
                    if (Globals::$conf->global->SOCIETE_ADD_REF_IN_LIST) {
1246
                        if (($obj->client) && (!empty($obj->code_client))) {
1247
                            $label = $obj->code_client . ' - ';
1248
                        }
1249
                        if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) {
1250
                            $label .= $obj->code_fournisseur . ' - ';
1251
                        }
1252
                        $label .= ' ' . $obj->name;
1253
                    } else {
1254
                        $label = $obj->name;
1255
                    }
1256
1257
                    if (!empty($obj->name_alias)) {
1258
                        $label .= ' (' . $obj->name_alias . ')';
1259
                    }
1260
1261
                    if ($showtype) {
1262
                        if ($obj->client || $obj->fournisseur)
1263
                            $label .= ' (';
1264
                        if ($obj->client == 1 || $obj->client == 3)
1265
                            $label .= $langs->trans("Customer");
1266
                        if ($obj->client == 2 || $obj->client == 3)
1267
                            $label .= ($obj->client == 3 ? ', ' : '') . $langs->trans("Prospect");
1268
                        if ($obj->fournisseur)
1269
                            $label .= ($obj->client ? ', ' : '') . $langs->trans("Supplier");
1270
                        if ($obj->client || $obj->fournisseur)
1271
                            $label .= ')';
1272
                    }
1273
1274
                    if (Globals::$conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
1275
                        $label .= '-' . $obj->address . '-' . $obj->zip . ' ' . $obj->town;
1276
                        if (!empty($obj->country_code)) {
1277
                            $label .= ' ' . $langs->trans('Country' . $obj->country_code);
1278
                        }
1279
                    }
1280
1281
                    if (empty($outputmode)) {
1282
                        if (in_array($obj->rowid, $selected)) {
1283
                            $out .= '<option value="' . $obj->rowid . '" selected>' . $label . '</option>';
1284
                        } else {
1285
                            $out .= '<option value="' . $obj->rowid . '">' . $label . '</option>';
1286
                        }
1287
                    } else {
1288
                        array_push($outarray, array('key' => $obj->rowid, 'value' => $label, 'label' => $label));
1289
                    }
1290
1291
                    $i++;
1292
                    if (($i % 10) == 0)
1293
                        $out .= "\n";
1294
                }
1295
            }
1296
            $out .= '</select>' . "\n";
1297
        }
1298
        else {
1299
            DolUtils::dol_print_error($this->db);
1300
        }
1301
1302
        $this->result = array('nbofthirdparties' => $num);
1303
1304
        if ($outputmode)
1305
            return $outarray;
1306
        return $out;
1307
    }
1308
1309
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1310
    /**
1311
     *    	Return HTML combo list of absolute discounts
1312
     *
1313
     *    	@param	string	$selected       Id remise fixe pre-selectionnee
1314
     *    	@param  string	$htmlname       Nom champ formulaire
1315
     *    	@param  string	$filter         Criteres optionnels de filtre
1316
     * 		@param	int		$socid			Id of thirdparty
1317
     * 		@param	int		$maxvalue		Max value for lines that can be selected
1318
     * 		@return	int						Return number of qualifed lines in list
1319
     */
1320
    function select_remises($selected, $htmlname, $filter, $socid, $maxvalue = 0)
1321
    {
1322
        // phpcs:enable
1323
        global $langs, $conf;
1324
1325
        // On recherche les remises
1326
        $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1327
        $sql .= " re.description, re.fk_facture_source";
1328
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
1329
        $sql .= " WHERE re.fk_soc = " . (int) $socid;
1330
        $sql .= " AND re.entity = " . Globals::$conf->entity;
1331
        if ($filter)
1332
            $sql .= " AND " . $filter;
1333
        $sql .= " ORDER BY re.description ASC";
1334
1335
        dol_syslog(get_class($this) . "::select_remises", LOG_DEBUG);
1336
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1337
        if ($resql) {
1338
            print '<select id="select_' . $htmlname . '" class="flat maxwidthonsmartphone" name="' . $htmlname . '">';
1339
            $num = $this->db->num_rows($resql);
1340
1341
            $qualifiedlines = $num;
1342
1343
            $i = 0;
1344
            if ($num) {
1345
                print '<option value="0">&nbsp;</option>';
1346
                while ($i < $num) {
1347
                    $obj = $this->db->fetch_object($resql);
1348
                    $desc = dol_trunc($obj->description, 40);
1349
                    if (preg_match('/\(CREDIT_NOTE\)/', $desc))
1350
                        $desc = preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
1351
                    if (preg_match('/\(DEPOSIT\)/', $desc))
1352
                        $desc = preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
1353
                    if (preg_match('/\(EXCESS RECEIVED\)/', $desc))
1354
                        $desc = preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
1355
                    if (preg_match('/\(EXCESS PAID\)/', $desc))
1356
                        $desc = preg_replace('/\(EXCESS PAID\)/', $langs->trans("ExcessPaid"), $desc);
1357
1358
                    $selectstring = '';
1359
                    if ($selected > 0 && $selected == $obj->rowid)
1360
                        $selectstring = ' selected';
1361
1362
                    $disabled = '';
1363
                    if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) {
1364
                        $qualifiedlines--;
1365
                        $disabled = ' disabled';
1366
                    }
1367
1368
                    if (!empty(Globals::$conf->global->MAIN_SHOW_FACNUMBER_IN_DISCOUNT_LIST) && !empty($obj->fk_facture_source)) {
1369
                        $tmpfac = new Facture($this->db);
1370
                        if ($tmpfac->fetch($obj->fk_facture_source) > 0)
1371
                            $desc = $desc . ' - ' . $tmpfac->ref;
1372
                    }
1373
1374
                    print '<option value="' . $obj->rowid . '"' . $selectstring . $disabled . '>' . $desc . ' (' . price($obj->amount_ht) . ' ' . $langs->trans("HT") . ' - ' . price($obj->amount_ttc) . ' ' . $langs->trans("TTC") . ')</option>';
1375
                    $i++;
1376
                }
1377
            }
1378
            print '</select>';
1379
            return $qualifiedlines;
1380
        }
1381
        else {
1382
            DolUtils::dol_print_error($this->db);
1383
            return -1;
1384
        }
1385
    }
1386
1387
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1388
    /**
1389
     * 	Return list of all contacts (for a third party or all)
1390
     *
1391
     * 	@param	int		$socid      	Id ot third party or 0 for all
1392
     * 	@param  string	$selected   	Id contact pre-selectionne
1393
     * 	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1394
     * 	@param  int		$showempty      0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list
1395
     * 	@param  string	$exclude        List of contacts id to exclude
1396
     * 	@param	string	$limitto		Disable answers that are not id in this array list
1397
     * 	@param	integer	$showfunction   Add function into label
1398
     * 	@param	string	$moreclass		Add more class to class style
1399
     * 	@param	integer	$showsoc	    Add company into label
1400
     * 	@param	int		$forcecombo		Force to use combo box
1401
     *  @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')))
1402
     *  @param	bool	$options_only	Return options only (for ajax treatment)
1403
     *  @param	string	$moreparam		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1404
     *  @param	string	$htmlid			Html id to use instead of htmlname
1405
     * 	@return	int						<0 if KO, Nb of contact in list if OK
1406
     *  @deprected						You can use selectcontacts directly (warning order of param was changed)
1407
     */
1408
    function select_contacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $showsoc = 0, $forcecombo = 0, $events = array(), $options_only = false, $moreparam = '', $htmlid = '')
1409
    {
1410
        // phpcs:enable
1411
        print $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid);
1412
        return $this->num;
1413
    }
1414
1415
    /**
1416
     * 	Return HTML code of the SELECT of list of all contacts (for a third party or all).
1417
     *  This also set the number of contacts found into $this->num
1418
     *
1419
     * @since 9.0 Add afterSelectContactOptions hook
1420
     *
1421
     * 	@param	int			$socid      	Id ot third party or 0 for all or -1 for empty list
1422
     * 	@param  array|int	$selected   	Array of ID of pre-selected contact id
1423
     * 	@param  string		$htmlname  	    Name of HTML field ('none' for a not editable field)
1424
     * 	@param  int			$showempty     	0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list
1425
     * 	@param  string		$exclude        List of contacts id to exclude
1426
     * 	@param	string		$limitto		Disable answers that are not id in this array list
1427
     * 	@param	integer		$showfunction   Add function into label
1428
     * 	@param	string		$moreclass		Add more class to class style
1429
     * 	@param	bool		$options_only	Return options only (for ajax treatment)
1430
     * 	@param	integer		$showsoc	    Add company into label
1431
     * 	@param	int			$forcecombo		Force to use combo box (so no ajax beautify effect)
1432
     *  @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')))
1433
     *  @param	string		$moreparam		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1434
     *  @param	string		$htmlid			Html id to use instead of htmlname
1435
     *  @param	bool		$multiple		add [] in the name of element and add 'multiple' attribut
1436
     * 	@return	 int						<0 if KO, Nb of contact in list if OK
1437
     */
1438
    function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $options_only = false, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false)
1439
    {
1440
        global $conf, $langs, $hookmanager, $action;
1441
1442
        $langs->load('companies');
1443
1444
        if (empty($htmlid))
1445
            $htmlid = $htmlname;
1446
1447
        if ($selected === '')
1448
            $selected = array();
1449
        else if (!is_array($selected))
1450
            $selected = array($selected);
1451
        $out = '';
1452
1453
        if (!is_object($hookmanager)) {
1454
            include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
1455
            $hookmanager = new HookManager($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1456
        }
1457
1458
        // We search third parties
1459
        $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste";
1460
        if ($showsoc > 0)
1461
            $sql .= " , s.nom as company";
1462
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople as sp";
1463
        if ($showsoc > 0)
1464
            $sql .= " LEFT OUTER JOIN  " . MAIN_DB_PREFIX . "societe as s ON s.rowid=sp.fk_soc";
1465
        $sql .= " WHERE sp.entity IN (" . getEntity('socpeople') . ")";
1466
        if ($socid > 0 || $socid == -1)
1467
            $sql .= " AND sp.fk_soc=" . $socid;
1468
        if (!empty(Globals::$conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX))
1469
            $sql .= " AND sp.statut <> 0";
1470
        $sql .= " ORDER BY sp.lastname ASC";
1471
1472
        dol_syslog(get_class($this) . "::select_contacts", LOG_DEBUG);
1473
        $resql = $this->db->query($sql);
1474
        if ($resql) {
1475
            $num = $this->db->num_rows($resql);
1476
1477
            if (Globals::$conf->use_javascript_ajax && !$forcecombo && !$options_only) {
1478
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1479
                $out .= ajax_combobox($htmlid, $events, Globals::$conf->global->CONTACT_USE_SEARCH_TO_SELECT);
1480
            }
1481
1482
            if ($htmlname != 'none' || $options_only)
1483
                $out .= '<select class="flat' . ($moreclass ? ' ' . $moreclass : '') . '" id="' . $htmlid . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . (!empty($moreparam) ? $moreparam : '') . '>';
1484
            if (($showempty == 1 || ($showempty == 3 && $num > 1)) && !$multiple)
1485
                $out .= '<option value="0"' . (in_array(0, $selected) ? ' selected' : '') . '>&nbsp;</option>';
1486
            if ($showempty == 2)
1487
                $out .= '<option value="0"' . (in_array(0, $selected) ? ' selected' : '') . '>' . $langs->trans("Internal") . '</option>';
1488
            $num = $this->db->num_rows($resql);
1489
            $i = 0;
1490
            if ($num) {
1491
                include_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
1492
                $contactstatic = new Contact($this->db);
1493
1494
                while ($i < $num) {
1495
                    $obj = $this->db->fetch_object($resql);
1496
1497
                    $contactstatic->id = $obj->rowid;
1498
                    $contactstatic->lastname = $obj->lastname;
1499
                    $contactstatic->firstname = $obj->firstname;
1500
                    if ($obj->statut == 1) {
1501
                        if ($htmlname != 'none') {
1502
                            $disabled = 0;
1503
                            if (is_array($exclude) && count($exclude) && in_array($obj->rowid, $exclude))
1504
                                $disabled = 1;
1505
                            if (is_array($limitto) && count($limitto) && !in_array($obj->rowid, $limitto))
1506
                                $disabled = 1;
1507
                            if (!empty($selected) && in_array($obj->rowid, $selected)) {
1508
                                $out .= '<option value="' . $obj->rowid . '"';
1509
                                if ($disabled)
1510
                                    $out .= ' disabled';
1511
                                $out .= ' selected>';
1512
                                $out .= $contactstatic->getFullName($langs);
1513
                                if ($showfunction && $obj->poste)
1514
                                    $out .= ' (' . $obj->poste . ')';
1515
                                if (($showsoc > 0) && $obj->company)
1516
                                    $out .= ' - (' . $obj->company . ')';
1517
                                $out .= '</option>';
1518
                            }
1519
                            else {
1520
                                $out .= '<option value="' . $obj->rowid . '"';
1521
                                if ($disabled)
1522
                                    $out .= ' disabled';
1523
                                $out .= '>';
1524
                                $out .= $contactstatic->getFullName($langs);
1525
                                if ($showfunction && $obj->poste)
1526
                                    $out .= ' (' . $obj->poste . ')';
1527
                                if (($showsoc > 0) && $obj->company)
1528
                                    $out .= ' - (' . $obj->company . ')';
1529
                                $out .= '</option>';
1530
                            }
1531
                        }
1532
                        else {
1533
                            if (in_array($obj->rowid, $selected)) {
1534
                                $out .= $contactstatic->getFullName($langs);
1535
                                if ($showfunction && $obj->poste)
1536
                                    $out .= ' (' . $obj->poste . ')';
1537
                                if (($showsoc > 0) && $obj->company)
1538
                                    $out .= ' - (' . $obj->company . ')';
1539
                            }
1540
                        }
1541
                    }
1542
                    $i++;
1543
                }
1544
            }
1545
            else {
1546
                $out .= '<option value="-1"' . (($showempty == 2 || $multiple) ? '' : ' selected') . ' disabled>';
1547
                $out .= ($socid != -1) ? ($langs->trans($socid ? "NoContactDefinedForThirdParty" : "NoContactDefined")) : $langs->trans('SelectAThirdPartyFirst');
1548
                $out .= '</option>';
1549
            }
1550
1551
            $parameters = array(
1552
                'socid' => $socid,
1553
                'htmlname' => $htmlname,
1554
                'resql' => $resql,
1555
                'out' => &$out,
1556
                'showfunction' => $showfunction,
1557
                'showsoc' => $showsoc,
1558
            );
1559
1560
            $reshook = $hookmanager->executeHooks('afterSelectContactOptions', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
1561
1562
            if ($htmlname != 'none' || $options_only) {
1563
                $out .= '</select>';
1564
            }
1565
1566
            $this->num = $num;
1567
            return $out;
1568
        } else {
1569
            DolUtils::dol_print_error($this->db);
1570
            return -1;
1571
        }
1572
    }
1573
1574
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1575
    /**
1576
     * 	Return select list of users
1577
     *
1578
     *  @param	string	$selected       Id user preselected
1579
     *  @param  string	$htmlname       Field name in form
1580
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1581
     *  @param  array	$exclude        Array list of users id to exclude
1582
     * 	@param	int		$disabled		If select list must be disabled
1583
     *  @param  array	$include        Array list of users id to include
1584
     * 	@param	int		$enableonly		Array list of users id to be enabled. All other must be disabled
1585
     *  @param	string	$force_entity	'0' or Ids of environment to force
1586
     * 	@return	void
1587
     *  @deprecated		Use select_dolusers instead
1588
     *  @see select_dolusers()
1589
     */
1590
    function select_users($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0')
1591
    {
1592
        // phpcs:enable
1593
        print $this->select_dolusers($selected, $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity);
1594
    }
1595
1596
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1597
    /**
1598
     * 	Return select list of users
1599
     *
1600
     *  @param	string	$selected       User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1, keep unselected (if empty is allowed)
1601
     *  @param  string	$htmlname       Field name in form
1602
     *  @param  int		$show_empty     0=list with no empty value, 1=add also an empty value into list
1603
     *  @param  array	$exclude        Array list of users id to exclude
1604
     * 	@param	int		$disabled		If select list must be disabled
1605
     *  @param  array|string	$include        Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me
1606
     * 	@param	array	$enableonly		Array list of users id to be enabled. If defined, it means that others will be disabled
1607
     *  @param	string	$force_entity	'0' or Ids of environment to force
1608
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1609
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1610
     *  @param	string	$morefilter		Add more filters into sql request (Example: 'employee = 1')
1611
     *  @param	integer	$show_every		0=default list, 1=add also a value "Everybody" at beginning of list
1612
     *  @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.
1613
     *  @param	string	$morecss		More css
1614
     *  @param  int     $noactive       Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on).
1615
     *  @param  int		$outputmode     0=HTML select string, 1=Array
1616
     *  @param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
1617
     * 	@return	string					HTML select string
1618
     *  @see select_dolgroups
1619
     */
1620
    function select_dolusers($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $show_every = 0, $enableonlytext = '', $morecss = '', $noactive = 0, $outputmode = 0, $multiple = false)
1621
    {
1622
        // phpcs:enable
1623
        global $conf, $user, $langs;
1624
1625
        // If no preselected user defined, we take current user
1626
        if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty(Globals::$conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE))
1627
            $selected = $user->id;
1628
1629
        if ($selected === '')
1630
            $selected = array();
1631
        else if (!is_array($selected))
1632
            $selected = array($selected);
1633
1634
        $excludeUsers = null;
1635
        $includeUsers = null;
1636
1637
        // Permettre l'exclusion d'utilisateurs
1638
        if (is_array($exclude))
1639
            $excludeUsers = implode(",", $exclude);
1640
        // Permettre l'inclusion d'utilisateurs
1641
        if (is_array($include))
1642
            $includeUsers = implode(",", $include);
1643
        else if ($include == 'hierarchy') {
1644
            // Build list includeUsers to have only hierarchy
1645
            $includeUsers = implode(",", $user->getAllChildIds(0));
1646
        } else if ($include == 'hierarchyme') {
1647
            // Build list includeUsers to have only hierarchy and current user
1648
            $includeUsers = implode(",", $user->getAllChildIds(1));
1649
        }
1650
1651
        $out = '';
1652
        $outarray = array();
1653
1654
        // Forge request to select users
1655
        $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1656
        if (!empty(Globals::$conf->multicompany->enabled) && Globals::$conf->entity == 1 && $user->admin && !$user->entity) {
1657
            $sql .= ", e.label";
1658
        }
1659
        $sql .= " FROM " . MAIN_DB_PREFIX . "user as u";
1660
        if (!empty(Globals::$conf->multicompany->enabled) && Globals::$conf->entity == 1 && $user->admin && !$user->entity) {
1661
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=u.entity";
1662
            if ($force_entity)
1663
                $sql .= " WHERE u.entity IN (0," . $force_entity . ")";
1664
            else
1665
                $sql .= " WHERE u.entity IS NOT NULL";
1666
        }
1667
        else {
1668
            if (!empty(Globals::$conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1669
                $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "usergroup_user as ug";
1670
                $sql .= " ON ug.fk_user = u.rowid";
1671
                $sql .= " WHERE ug.entity = " . Globals::$conf->entity;
1672
            } else {
1673
                $sql .= " WHERE u.entity IN (0," . Globals::$conf->entity . ")";
1674
            }
1675
        }
1676
        if (!empty($user->societe_id))
1677
            $sql .= " AND u.fk_soc = " . $user->societe_id;
1678
        if (is_array($exclude) && $excludeUsers)
1679
            $sql .= " AND u.rowid NOT IN (" . $excludeUsers . ")";
1680
        if ($includeUsers)
1681
            $sql .= " AND u.rowid IN (" . $includeUsers . ")";
1682
        if (!empty(Globals::$conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive)
1683
            $sql .= " AND u.statut <> 0";
1684
        if (!empty($morefilter))
1685
            $sql .= " " . $morefilter;
1686
1687
        if (empty(Globals::$conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { // MAIN_FIRSTNAME_NAME_POSITION is 0 means firstname+lastname
1688
            $sql .= " ORDER BY u.firstname ASC";
1689
        } else {
1690
            $sql .= " ORDER BY u.lastname ASC";
1691
        }
1692
1693
        dol_syslog(get_class($this) . "::select_dolusers", LOG_DEBUG);
1694
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1695
        if ($resql) {
1696
            $num = $this->db->num_rows($resql);
1697
            $i = 0;
1698
            if ($num) {
1699
                // Enhance with select2
1700
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1701
                $out .= ajax_combobox($htmlname);
1702
1703
                // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
1704
                $out .= '<select class="flat' . ($morecss ? ' minwidth100 ' . $morecss : ' minwidth200') . '" id="' . $htmlname . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . ($disabled ? ' disabled' : '') . '>';
1705
                if ($show_empty && !$multiple)
1706
                    $out .= '<option value="-1"' . ((empty($selected) || in_array(-1, $selected)) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
1707
                if ($show_every)
1708
                    $out .= '<option value="-2"' . ((in_array(-2, $selected)) ? ' selected' : '') . '>-- ' . $langs->trans("Everybody") . ' --</option>' . "\n";
1709
1710
                $userstatic = new User($this->db);
1711
1712
                while ($i < $num) {
1713
                    $obj = $this->db->fetch_object($resql);
1714
1715
                    $userstatic->id = $obj->rowid;
1716
                    $userstatic->lastname = $obj->lastname;
1717
                    $userstatic->firstname = $obj->firstname;
1718
1719
                    $disableline = '';
1720
                    if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly))
1721
                        $disableline = ($enableonlytext ? $enableonlytext : '1');
1722
1723
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (!is_object($selected) && in_array($obj->rowid, $selected) )) {
1724
                        $out .= '<option value="' . $obj->rowid . '"';
1725
                        if ($disableline)
1726
                            $out .= ' disabled';
1727
                        $out .= ' selected>';
1728
                    }
1729
                    else {
1730
                        $out .= '<option value="' . $obj->rowid . '"';
1731
                        if ($disableline)
1732
                            $out .= ' disabled';
1733
                        $out .= '>';
1734
                    }
1735
1736
                    // $fullNameMode is 0=Lastname+Firstname (MAIN_FIRSTNAME_NAME_POSITION=1), 1=Firstname+Lastname (MAIN_FIRSTNAME_NAME_POSITION=0)
1737
                    $fullNameMode = 0;
1738
                    if (empty(Globals::$conf->global->MAIN_FIRSTNAME_NAME_POSITION)) {
1739
                        $fullNameMode = 1; //Firstname+lastname
1740
                    }
1741
                    $out .= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
1742
1743
                    // Complete name with more info
1744
                    $moreinfo = 0;
1745
                    if (!empty(Globals::$conf->global->MAIN_SHOW_LOGIN)) {
1746
                        $out .= ($moreinfo ? ' - ' : ' (') . $obj->login;
1747
                        $moreinfo++;
1748
                    }
1749
                    if ($showstatus >= 0) {
1750
                        if ($obj->statut == 1 && $showstatus == 1) {
1751
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans('Enabled');
1752
                            $moreinfo++;
1753
                        }
1754
                        if ($obj->statut == 0) {
1755
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans('Disabled');
1756
                            $moreinfo++;
1757
                        }
1758
                    }
1759
                    if (!empty(Globals::$conf->multicompany->enabled) && empty(Globals::$conf->global->MULTICOMPANY_TRANSVERSE_MODE) && Globals::$conf->entity == 1 && $user->admin && !$user->entity) {
1760
                        if (!$obj->entity) {
1761
                            $out .= ($moreinfo ? ' - ' : ' (') . $langs->trans("AllEntities");
1762
                            $moreinfo++;
1763
                        } else {
1764
                            $out .= ($moreinfo ? ' - ' : ' (') . ($obj->label ? $obj->label : $langs->trans("EntityNameNotDefined"));
1765
                            $moreinfo++;
1766
                        }
1767
                    }
1768
                    $out .= ($moreinfo ? ')' : '');
1769
                    if ($disableline && $disableline != '1') {
1770
                        $out .= ' - ' . $disableline; // This is text from $enableonlytext parameter
1771
                    }
1772
                    $out .= '</option>';
1773
                    $outarray[$userstatic->id] = $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
1774
1775
                    $i++;
1776
                }
1777
            } else {
1778
                $out .= '<select class="flat" id="' . $htmlname . '" name="' . $htmlname . '" disabled>';
1779
                $out .= '<option value="">' . $langs->trans("None") . '</option>';
1780
            }
1781
            $out .= '</select>';
1782
        } else {
1783
            DolUtils::dol_print_error($this->db);
1784
        }
1785
1786
        if ($outputmode)
1787
            return $outarray;
1788
        return $out;
1789
    }
1790
1791
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1792
    /**
1793
     * 	Return select list of users. Selected users are stored into session.
1794
     *  List of users are provided into $_SESSION['assignedtouser'].
1795
     *
1796
     *  @param  string	$action         Value for $action
1797
     *  @param  string	$htmlname       Field name in form
1798
     *  @param  int		$show_empty     0=list without the empty value, 1=add empty value
1799
     *  @param  array	$exclude        Array list of users id to exclude
1800
     * 	@param	int		$disabled		If select list must be disabled
1801
     *  @param  array	$include        Array list of users id to include or 'hierarchy' to have only supervised users
1802
     * 	@param	array	$enableonly		Array list of users id to be enabled. All other must be disabled
1803
     *  @param	int		$force_entity	'0' or Ids of environment to force
1804
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1805
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1806
     *  @param	string	$morefilter		Add more filters into sql request
1807
     *  @param	int		$showproperties		Show properties of each attendees
1808
     *  @param	array	$listofuserid		Array with properties of each user
1809
     *  @param	array	$listofcontactid	Array with properties of each contact
1810
     *  @param	array	$listofotherid		Array with properties of each other contact
1811
     * 	@return	string					HTML select string
1812
     *  @see select_dolgroups
1813
     */
1814
    function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array())
1815
    {
1816
        // phpcs:enable
1817
        global $conf, $user, $langs;
1818
1819
        $userstatic = new User($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1820
        $out = '';
1821
1822
        // Method with no ajax
1823
        //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1824
        if ($action == 'view') {
1825
            $out .= '';
1826
        } else {
1827
            $out .= '<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">';
1828
            $out .= '<script type="text/javascript" language="javascript">jQuery(document).ready(function () {    jQuery(".removedassigned").click(function() {        jQuery(".removedassignedhidden").val(jQuery(this).val());    });})</script>';
1829
            $out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter);
1830
            $out .= ' <input type="submit" class="button valignmiddle" name="' . $action . 'assignedtouser" value="' . DolUtils::dol_escape_htmltag($langs->trans("Add")) . '">';
1831
            $out .= '<br>';
1832
        }
1833
        $assignedtouser = array();
1834
        if (!empty($_SESSION['assignedtouser'])) {
1835
            $assignedtouser = json_decode($_SESSION['assignedtouser'], true);
1836
        }
1837
        $nbassignetouser = count($assignedtouser);
1838
1839
        if ($nbassignetouser && $action != 'view')
1840
            $out .= '<br>';
1841
        if ($nbassignetouser)
1842
            $out .= '<ul class="attendees">';
1843
        $i = 0;
1844
        $ownerid = 0;
1845
        foreach ($assignedtouser as $key => $value) {
1846
            if ($value['id'] == $ownerid)
1847
                continue;
1848
1849
            $out .= '<li>';
1850
            $userstatic->fetch($value['id']);
1851
            $out .= $userstatic->getNomUrl(-1);
1852
            if ($i == 0) {
1853
                $ownerid = $value['id'];
1854
                $out .= ' (' . $langs->trans("Owner") . ')';
1855
            }
1856
            if ($nbassignetouser > 1 && $action != 'view') {
1857
                $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 . '">';
1858
            }
1859
            // Show my availability
1860
            if ($showproperties) {
1861
                if ($ownerid == $value['id'] && is_array($listofuserid) && count($listofuserid) && in_array($ownerid, array_keys($listofuserid))) {
1862
                    $out .= '<div class="myavailability inline-block">';
1863
                    $out .= '&nbsp;-&nbsp;<span class="opacitymedium">' . $langs->trans("Availability") . ':</span>  <input id="transparency" class="marginleftonly marginrightonly" ' . ($action == 'view' ? 'disabled' : '') . ' type="checkbox" name="transparency"' . ($listofuserid[$ownerid]['transparency'] ? ' checked' : '') . '>' . $langs->trans("Busy");
1864
                    $out .= '</div>';
1865
                }
1866
            }
1867
            //$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional"));
1868
            //$out.=' '.($value['transparency']?$langs->trans("Busy"):$langs->trans("NotBusy"));
1869
1870
            $out .= '</li>';
1871
            $i++;
1872
        }
1873
        if ($nbassignetouser)
1874
            $out .= '</ul>';
1875
1876
        //$out.='</form>';
1877
        return $out;
1878
    }
1879
1880
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1881
    /**
1882
     *  Return list of products for customer in Ajax if Ajax activated or go to select_produits_list
1883
     *
1884
     *  @param		int			$selected				Preselected products
1885
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1886
     *  @param		int			$filtertype				Filter on product type (''=nofilter, 0=product, 1=service)
1887
     *  @param		int			$limit					Limit on number of returned lines
1888
     *  @param		int			$price_level			Level of price to show
1889
     *  @param		int			$status					Sell status -1=Return all products, 0=Products not on sell, 1=Products on sell
1890
     *  @param		int			$finished				2=all, 1=finished, 0=raw material
1891
     *  @param		string		$selected_input_value	Value of preselected input text (for use with ajax)
1892
     *  @param		int			$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1893
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1894
     *  @param      int			$socid					Thirdparty Id (to get also price dedicated to this customer)
1895
     *  @param		string		$showempty				'' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1896
     * 	@param		int			$forcecombo				Force to use combo box
1897
     *  @param      string      $morecss                Add more css on select
1898
     *  @param      int         $hidepriceinlabel       1=Hide prices in label
1899
     *  @param      string      $warehouseStatus        warehouse status filter, following comma separated filter options can be used
1900
     * 										            'warehouseopen' = select products from open warehouses,
1901
     * 										            'warehouseclosed' = select products from closed warehouses,
1902
     * 										            'warehouseinternal' = select products from warehouses for internal correct/transfer only
1903
     *  @param 		array 		$selected_combinations 	Selected combinations. Format: array([attrid] => attrval, [...])
1904
     *  @return		void
1905
     */
1906
    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())
1907
    {
1908
        // phpcs:enable
1909
        global $langs, $conf;
1910
1911
        $price_level = (!empty($price_level) ? $price_level : 0);
1912
1913
        if (!empty(Globals::$conf->use_javascript_ajax) && !empty(Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
1914
            $placeholder = '';
1915
1916
            if ($selected && empty($selected_input_value)) {
1917
                require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
1918
                $producttmpselect = new Product($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
1919
                $producttmpselect->fetch($selected);
1920
                $selected_input_value = $producttmpselect->ref;
1921
                unset($producttmpselect);
1922
            }
1923
            // mode=1 means customers products
1924
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=1&status=' . $status . '&finished=' . $finished . '&hidepriceinlabel=' . $hidepriceinlabel . '&warehousestatus=' . $warehouseStatus;
1925
            //Price by customer
1926
            if (!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1927
                $urloption .= '&socid=' . $socid;
1928
            }
1929
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1930
1931
            if (!empty(Globals::$conf->variants->enabled)) {
1932
1933
                ?>
1934
                <script>
1935
1936
                                    selected = <?php echo json_encode($selected_combinations) ?>;
1937
                                    combvalues = {};
1938
1939
                                    jQuery(document).ready(function () {
1940
1941
                                        jQuery("input[name='prod_entry_mode']").change(function () {
1942
                                            if (jQuery(this).val() == 'free') {
1943
                                                jQuery('div#attributes_box').empty();
1944
                                            }
1945
                                        });
1946
1947
                                        jQuery("input#<?php echo $htmlname ?>").change(function () {
1948
1949
                                            if (!jQuery(this).val()) {
1950
                                                jQuery('div#attributes_box').empty();
1951
                                                return;
1952
                                            }
1953
1954
                                            jQuery.getJSON("<?php echo dol_buildpath('/variants/ajax/getCombinations.php', 2) ?>", {
1955
                                                id: jQuery(this).val()
1956
                                            }, function (data) {
1957
                                                jQuery('div#attributes_box').empty();
1958
1959
                                                jQuery.each(data, function (key, val) {
1960
1961
                                                    combvalues[val.id] = val.values;
1962
1963
                                                    var span = jQuery(document.createElement('div')).css({
1964
                                                        'display': 'table-row'
1965
                                                    });
1966
1967
                                                    span.append(
1968
                                                            jQuery(document.createElement('div')).text(val.label).css({
1969
                                                        'font-weight': 'bold',
1970
                                                        'display': 'table-cell',
1971
                                                        'text-align': 'right'
1972
                                                    })
1973
                                                            );
1974
1975
                                                    var html = jQuery(document.createElement('select')).attr('name', 'combinations[' + val.id + ']').css({
1976
                                                        'margin-left': '15px',
1977
                                                        'white-space': 'pre'
1978
                                                    }).append(
1979
                                                            jQuery(document.createElement('option')).val('')
1980
                                                            );
1981
1982
                                                    jQuery.each(combvalues[val.id], function (key, val) {
1983
                                                        var tag = jQuery(document.createElement('option')).val(val.id).html(val.value);
1984
1985
                                                        if (selected[val.fk_product_attribute] == val.id) {
1986
                                                            tag.attr('selected', 'selected');
1987
                                                        }
1988
1989
                                                        html.append(tag);
1990
                                                    });
1991
1992
                                                    span.append(html);
1993
                                                    jQuery('div#attributes_box').append(span);
1994
                                                });
1995
                                            })
1996
                                        });
1997
1998
                <?php if ($selected): ?>
1999
                                jQuery("input#<?php echo $htmlname ?>").change();
2000
                <?php endif ?>
2001
                    });
2002
                                </script>
2003
                                <?php
2004
                            }
2005
                            if (empty($hidelabel))
2006
                                print $langs->trans("RefOrLabel") . ' : ';
2007
                            else if ($hidelabel > 1) {
2008
                                $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
2009
                                if ($hidelabel == 2) {
2010
                                    print img_picto($langs->trans("Search"), 'search');
2011
                                }
2012
                            }
2013
                            print '<input type="text" class="minwidth100" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (!empty(Globals::$conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '') . ' />';
2014
                            if ($hidelabel == 3) {
2015
                                print img_picto($langs->trans("Search"), 'search');
2016
                            }
2017
                        } else {
2018
                            print $this->select_produits_list($selected, $htmlname, $filtertype, $limit, $price_level, '', $status, $finished, 0, $socid, $showempty, $forcecombo, $morecss, $hidepriceinlabel, $warehouseStatus);
2019
                        }
2020
                    }
2021
2022
                    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2023
                    /**
2024
                     * 	Return list of products for a customer
2025
                     *
2026
                     * 	@param      int		$selected           Preselected product
2027
                     * 	@param      string	$htmlname           Name of select html
2028
                     *  @param		string	$filtertype         Filter on product type (''=nofilter, 0=product, 1=service)
2029
                     * 	@param      int		$limit              Limit on number of returned lines
2030
                     * 	@param      int		$price_level        Level of price to show
2031
                     * 	@param      string	$filterkey          Filter on product
2032
                     * 	@param		int		$status             -1=Return all products, 0=Products not on sell, 1=Products on sell
2033
                     *  @param      int		$finished           Filter on finished field: 2=No filter
2034
                     *  @param      int		$outputmode         0=HTML select string, 1=Array
2035
                     *  @param      int		$socid     		    Thirdparty Id (to get also price dedicated to this customer)
2036
                     *  @param		string	$showempty		    '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
2037
                     * 	@param		int		$forcecombo		    Force to use combo box
2038
                     *  @param      string  $morecss            Add more css on select
2039
                     *  @param      int     $hidepriceinlabel   1=Hide prices in label
2040
                     *  @param      string  $warehouseStatus    warehouse status filter, following comma separated filter options can be used
2041
                     * 										    'warehouseopen' = select products from open warehouses,
2042
                     * 										    'warehouseclosed' = select products from closed warehouses,
2043
                     * 										    'warehouseinternal' = select products from warehouses for internal correct/transfer only
2044
                     *  @return     array    				    Array of keys for json
2045
                     */
2046
                    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 = '')
2047
                    {
2048
                        // phpcs:enable
2049
        global $langs, $conf, $user, $db;
2050
2051
        $out = '';
2052
        $outarray = array();
2053
2054
        $warehouseStatusArray = array();
2055
        if (!empty($warehouseStatus)) {
2056
            require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
2057
            if (preg_match('/warehouseclosed/', $warehouseStatus)) {
2058
                $warehouseStatusArray[] = Entrepot::STATUS_CLOSED;
2059
            }
2060
            if (preg_match('/warehouseopen/', $warehouseStatus)) {
2061
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL;
2062
            }
2063
            if (preg_match('/warehouseinternal/', $warehouseStatus)) {
2064
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL;
2065
            }
2066
        }
2067
2068
        $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";
2069
        (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock";
2070
2071
        $sql = "SELECT ";
2072
        $sql .= $selectFields . $selectFieldsGrouped;
2073
2074
        if (!empty(Globals::$conf->global->PRODUCT_SORT_BY_CATEGORY)) {
2075
            //Product category
2076
            $sql .= ", (SELECT " . MAIN_DB_PREFIX . "categorie_product.fk_categorie
2077
						FROM " . MAIN_DB_PREFIX . "categorie_product
2078
						WHERE " . MAIN_DB_PREFIX . "categorie_product.fk_product=p.rowid
2079
						LIMIT 1
2080
				) AS categorie_product_id ";
2081
        }
2082
2083
        //Price by customer
2084
        if (!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
2085
            $sql .= ', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
2086
            $sql .= ' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
2087
            $selectFields .= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
2088
        }
2089
2090
        // Multilang : we add translation
2091
        if (!empty(Globals::$conf->global->MAIN_MULTILANGS)) {
2092
            $sql .= ", pl.label as label_translated";
2093
            $selectFields .= ", label_translated";
2094
        }
2095
        // Price by quantity
2096
        if (!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
2097
            $sql .= ", (SELECT pp.rowid FROM " . MAIN_DB_PREFIX . "product_price as pp WHERE pp.fk_product = p.rowid";
2098
            if ($price_level >= 1 && !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
2099
                $sql .= " AND price_level=" . $price_level;
2100
            $sql .= " ORDER BY date_price";
2101
            $sql .= " DESC LIMIT 1) as price_rowid";
2102
            $sql .= ", (SELECT pp.price_by_qty FROM " . MAIN_DB_PREFIX . "product_price as pp WHERE pp.fk_product = p.rowid"; // price_by_qty is 1 if some prices by qty exists in subtable
2103
            if ($price_level >= 1 && !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
2104
                $sql .= " AND price_level=" . $price_level;
2105
            $sql .= " ORDER BY date_price";
2106
            $sql .= " DESC LIMIT 1) as price_by_qty";
2107
            $selectFields .= ", price_rowid, price_by_qty";
2108
        }
2109
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
2110
        if (count($warehouseStatusArray)) {
2111
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock as ps on ps.fk_product = p.rowid";
2112
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entrepot as e on ps.fk_entrepot = e.rowid";
2113
        }
2114
2115
        // include search in supplier ref
2116
        if (!empty(Globals::$conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) {
2117
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2118
        }
2119
2120
        //Price by customer
2121
        if (!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
2122
            $sql .= " LEFT JOIN  " . MAIN_DB_PREFIX . "product_customer_price as pcp ON pcp.fk_soc=" . $socid . " AND pcp.fk_product=p.rowid";
2123
        }
2124
        // Multilang : we add translation
2125
        if (!empty(Globals::$conf->global->MAIN_MULTILANGS)) {
2126
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='" . $langs->getDefaultLang() . "'";
2127
        }
2128
2129
        if (!empty(Globals::$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
2130
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination pac ON pac.fk_product_child = p.rowid";
2131
        }
2132
2133
        $sql .= ' WHERE p.entity IN (' . getEntity('product') . ')';
2134
        if (count($warehouseStatusArray)) {
2135
            $sql .= ' AND (p.fk_product_type = 1 OR e.statut IN (' . $this->db->escape(implode(',', $warehouseStatusArray)) . '))';
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2136
        }
2137
2138
        if (!empty(Globals::$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
2139
            $sql .= " AND pac.rowid IS NULL";
2140
        }
2141
2142
        if ($finished == 0) {
2143
            $sql .= " AND p.finished = " . $finished;
2144
        } elseif ($finished == 1) {
2145
            $sql .= " AND p.finished = " . $finished;
2146
            if ($status >= 0)
2147
                $sql .= " AND p.tosell = " . $status;
2148
        }
2149
        elseif ($status >= 0) {
2150
            $sql .= " AND p.tosell = " . $status;
2151
        }
2152
        if (strval($filtertype) != '')
2153
            $sql .= " AND p.fk_product_type=" . $filtertype;
2154
        // Add criteria on ref/label
2155
        if ($filterkey != '') {
2156
            $sql .= ' AND (';
2157
            $prefix = empty(Globals::$conf->global->PRODUCT_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2158
            // For natural search
2159
            $scrit = explode(' ', $filterkey);
2160
            $i = 0;
2161
            if (count($scrit) > 1)
2162
                $sql .= "(";
2163
            foreach ($scrit as $crit) {
2164
                if ($i > 0)
2165
                    $sql .= " AND ";
2166
                $sql .= "(p.ref LIKE '" . $db->escape($prefix . $crit) . "%' OR p.label LIKE '" . $db->escape($prefix . $crit) . "%'";
2167
                if (!empty(Globals::$conf->global->MAIN_MULTILANGS))
2168
                    $sql .= " OR pl.label LIKE '" . $db->escape($prefix . $crit) . "%'";
2169
                if (!empty(Globals::$conf->global->PRODUCT_AJAX_SEARCH_ON_DESCRIPTION)) {
2170
                    $sql .= " OR p.description LIKE '" . $db->escape($prefix . $crit) . "%'";
2171
                    if (!empty(Globals::$conf->global->MAIN_MULTILANGS))
2172
                        $sql .= " OR pl.description LIKE '" . $db->escape($prefix . $crit) . "%'";
2173
                }
2174
                if (!empty(Globals::$conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF))
2175
                    $sql .= " OR pfp.ref_fourn LIKE '" . $db->escape($prefix . $crit) . "%'";
2176
                $sql .= ")";
2177
                $i++;
2178
            }
2179
            if (count($scrit) > 1)
2180
                $sql .= ")";
2181
            if (!empty(Globals::$conf->barcode->enabled))
2182
                $sql .= " OR p.barcode LIKE '" . $db->escape($prefix . $filterkey) . "%'";
2183
            $sql .= ')';
2184
        }
2185
        if (count($warehouseStatusArray)) {
2186
            $sql .= ' GROUP BY' . $selectFields;
2187
        }
2188
2189
        //Sort by category
2190
        if (!empty(Globals::$conf->global->PRODUCT_SORT_BY_CATEGORY)) {
2191
            $sql .= " ORDER BY categorie_product_id ";
2192
            //ASC OR DESC order
2193
            (Globals::$conf->global->PRODUCT_SORT_BY_CATEGORY == 1) ? $sql .= "ASC" : $sql .= "DESC";
2194
        } else {
2195
            $sql .= $db->order("p.ref");
2196
        }
2197
2198
        $sql .= $db->plimit($limit, 0);
2199
2200
        // Build output string
2201
        dol_syslog(get_class($this) . "::select_produits_list search product", LOG_DEBUG);
2202
        $result = $this->db->query($sql);
2203
        if ($result) {
2204
            require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
2205
            require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2206
            $num = $this->db->num_rows($result);
2207
2208
            $events = null;
2209
2210
            if (!$forcecombo) {
2211
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
2212
                $out .= ajax_combobox($htmlname, $events, Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
2213
            }
2214
2215
            $out .= '<select class="flat' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" id="' . $htmlname . '">';
2216
2217
            $textifempty = '';
2218
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
2219
            //if (! empty(Globals::$conf->use_javascript_ajax) || $forcecombo) $textifempty='';
2220
            if (!empty(Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
2221
                if ($showempty && !is_numeric($showempty))
2222
                    $textifempty = $langs->trans($showempty);
2223
                else
2224
                    $textifempty .= $langs->trans("All");
2225
            }
2226
            if ($showempty)
2227
                $out .= '<option value="0" selected>' . $textifempty . '</option>';
2228
2229
            $i = 0;
2230
            while ($num && $i < $num) {
2231
                $opt = '';
2232
                $optJson = array();
2233
                $objp = $this->db->fetch_object($result);
2234
2235
                if ((!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) { // Price by quantity will return many prices for the same product
2236
                    $sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise, price_base_type";
2237
                    $sql .= " FROM " . MAIN_DB_PREFIX . "product_price_by_qty";
2238
                    $sql .= " WHERE fk_product_price=" . $objp->price_rowid;
2239
                    $sql .= " ORDER BY quantity ASC";
2240
2241
                    dol_syslog(get_class($this) . "::select_produits_list search price by qty", LOG_DEBUG);
2242
                    $result2 = $this->db->query($sql);
2243
                    if ($result2) {
2244
                        $nb_prices = $this->db->num_rows($result2);
2245
                        $j = 0;
2246
                        while ($nb_prices && $j < $nb_prices) {
2247
                            $objp2 = $this->db->fetch_object($result2);
2248
2249
                            $objp->price_by_qty_rowid = $objp2->rowid;
2250
                            $objp->price_by_qty_price_base_type = $objp2->price_base_type;
2251
                            $objp->price_by_qty_quantity = $objp2->quantity;
2252
                            $objp->price_by_qty_unitprice = $objp2->unitprice;
2253
                            $objp->price_by_qty_remise_percent = $objp2->remise_percent;
2254
                            // For backward compatibility
2255
                            $objp->quantity = $objp2->quantity;
2256
                            $objp->price = $objp2->price;
2257
                            $objp->unitprice = $objp2->unitprice;
2258
                            $objp->remise_percent = $objp2->remise_percent;
2259
                            $objp->remise = $objp2->remise;
2260
2261
                            $this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel);
2262
2263
                            $j++;
2264
2265
                            // Add new entry
2266
                            // "key" value of json key array is used by jQuery automatically as selected value
2267
                            // "label" value of json key array is used by jQuery automatically as text for combo box
2268
                            $out .= $opt;
2269
                            array_push($outarray, $optJson);
2270
                        }
2271
                    }
2272
                } else {
2273
                    if (!empty(Globals::$conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) {
2274
                        $price_product = new Product($this->db);
2275
                        $price_product->fetch($objp->rowid, '', '', 1);
2276
                        $priceparser = new PriceParser($this->db);
2277
                        $price_result = $priceparser->parseProduct($price_product);
2278
                        if ($price_result >= 0) {
2279
                            $objp->price = $price_result;
2280
                            $objp->unitprice = $price_result;
2281
                            //Calculate the VAT
2282
                            $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100));
2283
                            $objp->price_ttc = price2num($objp->price_ttc, 'MU');
2284
                        }
2285
                    }
2286
                    $this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel);
2287
                    // Add new entry
2288
                    // "key" value of json key array is used by jQuery automatically as selected value
2289
                    // "label" value of json key array is used by jQuery automatically as text for combo box
2290
                    $out .= $opt;
2291
                    array_push($outarray, $optJson);
2292
                }
2293
2294
                $i++;
2295
            }
2296
2297
            $out .= '</select>';
2298
2299
            $this->db->free($result);
2300
2301
            if (empty($outputmode))
2302
                return $out;
2303
            return $outarray;
2304
        }
2305
        else {
2306
            DolUtils::dol_print_error($db);
2307
        }
2308
    }
2309
2310
    /**
2311
     * constructProductListOption
2312
     *
2313
     * @param 	resultset	$objp			    Resultset of fetch
2314
     * @param 	string		$opt			    Option (var used for returned value in string option format)
2315
     * @param 	string		$optJson		    Option (var used for returned value in json format)
2316
     * @param 	int			$price_level	    Price level
2317
     * @param 	string		$selected		    Preselected value
2318
     * @param   int         $hidepriceinlabel   Hide price in label
2319
     * @return	void
2320
     */
2321
    private function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0)
2322
    {
2323
        global $langs, $conf, $user, $db;
2324
2325
        $outkey = '';
2326
        $outval = '';
2327
        $outref = '';
2328
        $outlabel = '';
2329
        $outdesc = '';
2330
        $outbarcode = '';
2331
        $outtype = '';
2332
        $outprice_ht = '';
2333
        $outprice_ttc = '';
2334
        $outpricebasetype = '';
2335
        $outtva_tx = '';
2336
        $outqty = 1;
2337
        $outdiscount = 0;
2338
2339
        $maxlengtharticle = (empty(Globals::$conf->global->PRODUCT_MAX_LENGTH_COMBO) ? 48 : Globals::$conf->global->PRODUCT_MAX_LENGTH_COMBO);
2340
2341
        $label = $objp->label;
2342
        if (!empty($objp->label_translated))
2343
            $label = $objp->label_translated;
2344
        if (!empty($filterkey) && $filterkey != '')
2345
            $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
2346
2347
        $outkey = $objp->rowid;
2348
        $outref = $objp->ref;
2349
        $outlabel = $objp->label;
2350
        $outdesc = $objp->description;
2351
        $outbarcode = $objp->barcode;
2352
2353
        $outtype = $objp->fk_product_type;
2354
        $outdurationvalue = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : '';
2355
        $outdurationunit = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, -1) : '';
2356
2357
        $opt = '<option value="' . $objp->rowid . '"';
2358
        $opt .= ($objp->rowid == $selected) ? ' selected' : '';
2359
        if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0) {
2360
            $opt .= ' pbq="' . $objp->price_by_qty_rowid . '" data-pbq="' . $objp->price_by_qty_rowid . '" data-pbqqty="' . $objp->price_by_qty_quantity . '" data-pbqpercent="' . $objp->price_by_qty_remise_percent . '"';
2361
        }
2362
        if (!empty(Globals::$conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock)) {
2363
            if ($objp->stock > 0)
2364
                $opt .= ' class="product_line_stock_ok"';
2365
            else if ($objp->stock <= 0)
2366
                $opt .= ' class="product_line_stock_too_low"';
2367
        }
2368
        $opt .= '>';
2369
        $opt .= $objp->ref;
2370
        if ($outbarcode)
2371
            $opt .= ' (' . $outbarcode . ')';
2372
        $opt .= ' - ' . dol_trunc($label, $maxlengtharticle);
2373
2374
        $objRef = $objp->ref;
2375
        if (!empty($filterkey) && $filterkey != '')
2376
            $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
2377
        $outval .= $objRef;
2378
        if ($outbarcode)
2379
            $outval .= ' (' . $outbarcode . ')';
2380
        $outval .= ' - ' . dol_trunc($label, $maxlengtharticle);
2381
2382
        $found = 0;
2383
2384
        // Multiprice
2385
        // If we need a particular price level (from 1 to 6)
2386
        if (empty($hidepriceinlabel) && $price_level >= 1 && (!empty(Globals::$conf->global->PRODUIT_MULTIPRICES) || !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) {
2387
            $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
2388
            $sql .= " FROM " . MAIN_DB_PREFIX . "product_price";
2389
            $sql .= " WHERE fk_product='" . $objp->rowid . "'";
2390
            $sql .= " AND entity IN (" . getEntity('productprice') . ")";
2391
            $sql .= " AND price_level=" . $price_level;
2392
            $sql .= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid.
2393
            $sql .= " LIMIT 1";
2394
2395
            dol_syslog(get_class($this) . '::constructProductListOption search price for level ' . $price_level . '', LOG_DEBUG);
2396
            $result2 = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2397
            if ($result2) {
2398
                $objp2 = $this->db->fetch_object($result2);
2399
                if ($objp2) {
2400
                    $found = 1;
2401
                    if ($objp2->price_base_type == 'HT') {
2402
                        $opt .= ' - ' . price($objp2->price, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("HT");
2403
                        $outval .= ' - ' . price($objp2->price, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("HT");
2404
                    } else {
2405
                        $opt .= ' - ' . price($objp2->price_ttc, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("TTC");
2406
                        $outval .= ' - ' . price($objp2->price_ttc, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("TTC");
2407
                    }
2408
                    $outprice_ht = price($objp2->price);
2409
                    $outprice_ttc = price($objp2->price_ttc);
2410
                    $outpricebasetype = $objp2->price_base_type;
2411
                    $outtva_tx = $objp2->tva_tx;
2412
                }
2413
            } else {
2414
                DolUtils::dol_print_error($this->db);
2415
            }
2416
        }
2417
2418
        // Price by quantity
2419
        if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && (!empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) {
2420
            $found = 1;
2421
            $outqty = $objp->quantity;
2422
            $outdiscount = $objp->remise_percent;
2423
            if ($objp->quantity == 1) {
2424
                $opt .= ' - ' . price($objp->unitprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/";
2425
                $outval .= ' - ' . price($objp->unitprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/";
2426
                $opt .= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding
2427
                $outval .= $langs->transnoentities("Unit");
2428
            } else {
2429
                $opt .= ' - ' . price($objp->price, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $objp->quantity;
2430
                $outval .= ' - ' . price($objp->price, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $objp->quantity;
2431
                $opt .= $langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding
2432
                $outval .= $langs->transnoentities("Units");
2433
            }
2434
2435
            $outprice_ht = price($objp->unitprice);
2436
            $outprice_ttc = price($objp->unitprice * (1 + ($objp->tva_tx / 100)));
2437
            $outpricebasetype = $objp->price_base_type;
2438
            $outtva_tx = $objp->tva_tx;
2439
        }
2440
        if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1) {
2441
            $opt .= " (" . price($objp->unitprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $langs->trans("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2442
            $outval .= " (" . price($objp->unitprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $langs->transnoentities("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2443
        }
2444
        if (empty($hidepriceinlabel) && !empty($objp->remise_percent) && $objp->remise_percent >= 1) {
2445
            $opt .= " - " . $langs->trans("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2446
            $outval .= " - " . $langs->transnoentities("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2447
        }
2448
2449
        // Price by customer
2450
        if (empty($hidepriceinlabel) && !empty(Globals::$conf->global->PRODUIT_CUSTOMER_PRICES)) {
2451
            if (!empty($objp->idprodcustprice)) {
2452
                $found = 1;
2453
2454
                if ($objp->custprice_base_type == 'HT') {
2455
                    $opt .= ' - ' . price($objp->custprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("HT");
2456
                    $outval .= ' - ' . price($objp->custprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("HT");
2457
                } else {
2458
                    $opt .= ' - ' . price($objp->custprice_ttc, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("TTC");
2459
                    $outval .= ' - ' . price($objp->custprice_ttc, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("TTC");
2460
                }
2461
2462
                $outprice_ht = price($objp->custprice);
2463
                $outprice_ttc = price($objp->custprice_ttc);
2464
                $outpricebasetype = $objp->custprice_base_type;
2465
                $outtva_tx = $objp->custtva_tx;
2466
            }
2467
        }
2468
2469
        // If level no defined or multiprice not found, we used the default price
2470
        if (empty($hidepriceinlabel) && !$found) {
2471
            if ($objp->price_base_type == 'HT') {
2472
                $opt .= ' - ' . price($objp->price, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("HT");
2473
                $outval .= ' - ' . price($objp->price, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("HT");
2474
            } else {
2475
                $opt .= ' - ' . price($objp->price_ttc, 1, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->trans("TTC");
2476
                $outval .= ' - ' . price($objp->price_ttc, 0, $langs, 0, 0, -1, Globals::$conf->currency) . ' ' . $langs->transnoentities("TTC");
2477
            }
2478
            $outprice_ht = price($objp->price);
2479
            $outprice_ttc = price($objp->price_ttc);
2480
            $outpricebasetype = $objp->price_base_type;
2481
            $outtva_tx = $objp->tva_tx;
2482
        }
2483
2484
        if (!empty(Globals::$conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0) {
2485
            $opt .= ' - ' . $langs->trans("Stock") . ':' . $objp->stock;
2486
2487
            if ($objp->stock > 0) {
2488
                $outval .= ' - <span class="product_line_stock_ok">' . $langs->transnoentities("Stock") . ':' . $objp->stock . '</span>';
2489
            } elseif ($objp->stock <= 0) {
2490
                $outval .= ' - <span class="product_line_stock_too_low">' . $langs->transnoentities("Stock") . ':' . $objp->stock . '</span>';
2491
            }
2492
        }
2493
2494
        if ($outdurationvalue && $outdurationunit) {
2495
            $da = array("h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year"));
2496
            if (isset($da[$outdurationunit])) {
2497
                $key = $da[$outdurationunit] . ($outdurationvalue > 1 ? 's' : '');
2498
                $opt .= ' - ' . $outdurationvalue . ' ' . $langs->trans($key);
2499
                $outval .= ' - ' . $outdurationvalue . ' ' . $langs->transnoentities($key);
2500
            }
2501
        }
2502
2503
        $opt .= "</option>\n";
2504
        $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);
2505
    }
2506
2507
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2508
    /**
2509
     * 	Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list)
2510
     *
2511
     * 	@param	int		$socid			Id third party
2512
     * 	@param  string	$selected       Preselected product
2513
     * 	@param  string	$htmlname       Name of HTML Select
2514
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2515
     * 	@param  string	$filtre			For a SQL filter
2516
     * 	@param	array	$ajaxoptions	Options for ajax_autocompleter
2517
     *  @param	int		$hidelabel		Hide label (0=no, 1=yes)
2518
     *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2519
     * 	@return	void
2520
     */
2521
    function select_produits_fournisseurs($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $ajaxoptions = array(), $hidelabel = 0, $alsoproductwithnosupplierprice = 0)
2522
    {
2523
        // phpcs:enable
2524
        global $langs, $conf;
2525
        global $price_level, $status, $finished;
2526
2527
        $selected_input_value = '';
2528
        if (!empty(Globals::$conf->use_javascript_ajax) && !empty(Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
2529
            if ($selected > 0) {
2530
                require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
2531
                $producttmpselect = new Product($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2532
                $producttmpselect->fetch($selected);
2533
                $selected_input_value = $producttmpselect->ref;
2534
                unset($producttmpselect);
2535
            }
2536
2537
            // mode=2 means suppliers products
2538
            $urloption = ($socid > 0 ? 'socid=' . $socid . '&' : '') . 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=2&status=' . $status . '&finished=' . $finished . '&alsoproductwithnosupplierprice=' . $alsoproductwithnosupplierprice;
2539
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, Globals::$conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
2540
            print ($hidelabel ? '' : $langs->trans("RefOrLabel") . ' : ') . '<input type="text" size="20" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '">';
2541
        } else {
2542
            print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', -1, 0, 0, $alsoproductwithnosupplierprice);
2543
        }
2544
    }
2545
2546
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2547
    /**
2548
     * 	Return list of suppliers products
2549
     *
2550
     * 	@param	int		$socid   		Id societe fournisseur (0 pour aucun filtre)
2551
     * 	@param  int		$selected       Product price pre-selected (must be 'id' in product_fournisseur_price or 'idprod_IDPROD')
2552
     * 	@param  string	$htmlname       Nom de la zone select
2553
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2554
     * 	@param  string	$filtre         Pour filtre sql
2555
     * 	@param  string	$filterkey      Filtre des produits
2556
     *  @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)
2557
     *  @param  int		$outputmode     0=HTML select string, 1=Array
2558
     *  @param  int     $limit          Limit of line number
2559
     *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2560
     *  @return array           		Array of keys for json
2561
     */
2562
    function select_produits_fournisseurs_list($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $filterkey = '', $statut = -1, $outputmode = 0, $limit = 100, $alsoproductwithnosupplierprice = 0)
2563
    {
2564
        // phpcs:enable
2565
        global $langs, $conf, $db;
2566
2567
        $out = '';
2568
        $outarray = array();
2569
2570
        $langs->load('stocks');
2571
2572
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
2573
        $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
2574
        $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
2575
        $sql .= " pfp.supplier_reputation";
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
        if ($socid)
2579
            $sql .= " AND pfp.fk_soc = " . $socid;
2580
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON pfp.fk_soc = s.rowid";
2581
        $sql .= " WHERE p.entity IN (" . getEntity('product') . ")";
2582
        $sql .= " AND p.tobuy = 1";
2583
        if (strval($filtertype) != '')
2584
            $sql .= " AND p.fk_product_type=" . $this->db->escape($filtertype);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2585
        if (!empty($filtre))
2586
            $sql .= " " . $filtre;
2587
        // Add criteria on ref/label
2588
        if ($filterkey != '') {
2589
            $sql .= ' AND (';
2590
            $prefix = empty(Globals::$conf->global->PRODUCT_DONOTSEARCH_ANYWHERE) ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2591
            // For natural search
2592
            $scrit = explode(' ', $filterkey);
2593
            $i = 0;
2594
            if (count($scrit) > 1)
2595
                $sql .= "(";
2596
            foreach ($scrit as $crit) {
2597
                if ($i > 0)
2598
                    $sql .= " AND ";
2599
                $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) . "%')";
2600
                $i++;
2601
            }
2602
            if (count($scrit) > 1)
2603
                $sql .= ")";
2604
            if (!empty(Globals::$conf->barcode->enabled))
2605
                $sql .= " OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'";
2606
            $sql .= ')';
2607
        }
2608
        $sql .= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC";
2609
        $sql .= $db->plimit($limit, 0);
2610
2611
        // Build output string
2612
2613
        dol_syslog(get_class($this) . "::select_produits_fournisseurs_list", LOG_DEBUG);
2614
        $result = $this->db->query($sql);
2615
        if ($result) {
2616
            require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2617
2618
            $num = $this->db->num_rows($result);
2619
2620
            //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">';	// remove select to have id same with combo and ajax
2621
            $out .= '<select class="flat maxwidthonsmartphone" id="' . $htmlname . '" name="' . $htmlname . '">';
2622
            if (!$selected)
2623
                $out .= '<option value="0" selected>&nbsp;</option>';
2624
            else
2625
                $out .= '<option value="0">&nbsp;</option>';
2626
2627
            $i = 0;
2628
            while ($i < $num) {
2629
                $objp = $this->db->fetch_object($result);
2630
2631
                $outkey = $objp->idprodfournprice;                                                    // id in table of price
2632
                if (!$outkey && $alsoproductwithnosupplierprice)
2633
                    $outkey = 'idprod_' . $objp->rowid;   // id of product
2634
2635
                $outref = $objp->ref;
2636
                $outval = '';
2637
                $outqty = 1;
2638
                $outdiscount = 0;
2639
                $outtype = $objp->fk_product_type;
2640
                $outdurationvalue = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : '';
2641
                $outdurationunit = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, -1) : '';
2642
2643
                $opt = '<option value="' . $outkey . '"';
2644
                if ($selected && $selected == $objp->idprodfournprice)
2645
                    $opt .= ' selected';
2646
                if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice))
2647
                    $opt .= ' disabled';
2648
                if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0) {
2649
                    $opt .= ' pbq="' . $objp->idprodfournprice . '" data-pbq="' . $objp->idprodfournprice . '" data-pbqqty="' . $objp->quantity . '" data-pbqpercent="' . $objp->remise_percent . '"';
2650
                }
2651
                $opt .= '>';
2652
2653
                $objRef = $objp->ref;
2654
                if ($filterkey && $filterkey != '')
2655
                    $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
2656
                $objRefFourn = $objp->ref_fourn;
2657
                if ($filterkey && $filterkey != '')
2658
                    $objRefFourn = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRefFourn, 1);
2659
                $label = $objp->label;
2660
                if ($filterkey && $filterkey != '')
2661
                    $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
2662
2663
                $opt .= $objp->ref;
2664
                if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2665
                    $opt .= ' (' . $objp->ref_fourn . ')';
2666
                $opt .= ' - ';
2667
                $outval .= $objRef;
2668
                if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2669
                    $outval .= ' (' . $objRefFourn . ')';
2670
                $outval .= ' - ';
2671
                $opt .= dol_trunc($label, 72) . ' - ';
2672
                $outval .= dol_trunc($label, 72) . ' - ';
2673
2674
                if (!empty($objp->idprodfournprice)) {
2675
                    $outqty = $objp->quantity;
2676
                    $outdiscount = $objp->remise_percent;
2677
                    if (!empty(Globals::$conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2678
                        $prod_supplier = new ProductFournisseur($this->db);
2679
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2680
                        $prod_supplier->id = $objp->fk_product;
2681
                        $prod_supplier->fourn_qty = $objp->quantity;
2682
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2683
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2684
                        $priceparser = new PriceParser($this->db);
2685
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2686
                        if ($price_result >= 0) {
2687
                            $objp->fprice = $price_result;
2688
                            if ($objp->quantity >= 1) {
2689
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2690
                            }
2691
                        }
2692
                    }
2693
                    if ($objp->quantity == 1) {
2694
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/";
2695
                        $outval .= price($objp->fprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/";
2696
                        $opt .= $langs->trans("Unit"); // Do not use strtolower because it breaks utf8 encoding
2697
                        $outval .= $langs->transnoentities("Unit");
2698
                    } else {
2699
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $objp->quantity;
2700
                        $outval .= price($objp->fprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $objp->quantity;
2701
                        $opt .= ' ' . $langs->trans("Units"); // Do not use strtolower because it breaks utf8 encoding
2702
                        $outval .= ' ' . $langs->transnoentities("Units");
2703
                    }
2704
2705
                    if ($objp->quantity >= 1) {
2706
                        $opt .= " (" . price($objp->unitprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $langs->trans("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2707
                        $outval .= " (" . price($objp->unitprice, 0, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $langs->transnoentities("Unit") . ")"; // Do not use strtolower because it breaks utf8 encoding
2708
                    }
2709
                    if ($objp->remise_percent >= 1) {
2710
                        $opt .= " - " . $langs->trans("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2711
                        $outval .= " - " . $langs->transnoentities("Discount") . " : " . vatrate($objp->remise_percent) . ' %';
2712
                    }
2713
                    if ($objp->duration) {
2714
                        $opt .= " - " . $objp->duration;
2715
                        $outval .= " - " . $objp->duration;
2716
                    }
2717
                    if (!$socid) {
2718
                        $opt .= " - " . dol_trunc($objp->name, 8);
2719
                        $outval .= " - " . dol_trunc($objp->name, 8);
2720
                    }
2721
                    if ($objp->supplier_reputation) {
2722
                        //TODO dictionary
2723
                        $reputations = array('' => $langs->trans('Standard'), 'FAVORITE' => $langs->trans('Favorite'), 'NOTTHGOOD' => $langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER' => $langs->trans('DoNotOrderThisProductToThisSupplier'));
2724
2725
                        $opt .= " - " . $reputations[$objp->supplier_reputation];
2726
                        $outval .= " - " . $reputations[$objp->supplier_reputation];
2727
                    }
2728
                } else {
2729
                    if (empty($alsoproductwithnosupplierprice)) {     // No supplier price defined for couple product/supplier
2730
                        $opt .= $langs->trans("NoPriceDefinedForThisSupplier");
2731
                        $outval .= $langs->transnoentities("NoPriceDefinedForThisSupplier");
2732
                    } else {                                            // No supplier price defined for product, even on other suppliers
2733
                        $opt .= $langs->trans("NoPriceDefinedForThisSupplier");
2734
                        $outval .= $langs->transnoentities("NoPriceDefinedForThisSupplier");
2735
                    }
2736
                }
2737
                $opt .= "</option>\n";
2738
2739
2740
                // Add new entry
2741
                // "key" value of json key array is used by jQuery automatically as selected value
2742
                // "label" value of json key array is used by jQuery automatically as text for combo box
2743
                $out .= $opt;
2744
                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)));
2745
                // Exemple of var_dump $outarray
2746
                // array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp"
2747
                //           ["label"]=>string(76) "ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)"
2748
                //      	 ["qty"]=>string(1) "1" ["discount"]=>string(1) "0" ["disabled"]=>bool(false)
2749
                //}
2750
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2751
                //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)');
2752
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2753
2754
                $i++;
2755
            }
2756
            $out .= '</select>';
2757
2758
            $this->db->free($result);
2759
2760
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
2761
            $out .= ajax_combobox($htmlname);
2762
2763
            if (empty($outputmode))
2764
                return $out;
2765
            return $outarray;
2766
        }
2767
        else {
2768
            DolUtils::dol_print_error($this->db);
2769
        }
2770
    }
2771
2772
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2773
    /**
2774
     * 	Return list of suppliers prices for a product
2775
     *
2776
     *  @param	    int		$productid       	Id of product
2777
     *  @param      string	$htmlname        	Name of HTML field
2778
     *  @param      int		$selected_supplier  Pre-selected supplier if more than 1 result
2779
     *  @return	    void
2780
     */
2781
    function select_product_fourn_price($productid, $htmlname = 'productfournpriceid', $selected_supplier = '')
2782
    {
2783
        // phpcs:enable
2784
        global $langs, $conf;
2785
2786
        $langs->load('stocks');
2787
2788
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,";
2789
        $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,";
2790
        $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
2791
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
2792
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2793
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON pfp.fk_soc = s.rowid";
2794
        $sql .= " WHERE pfp.entity IN (" . getEntity('productsupplierprice') . ")";
2795
        $sql .= " AND p.tobuy = 1";
2796
        $sql .= " AND s.fournisseur = 1";
2797
        $sql .= " AND p.rowid = " . $productid;
2798
        $sql .= " ORDER BY s.nom, pfp.ref_fourn DESC";
2799
2800
        dol_syslog(get_class($this) . "::select_product_fourn_price", LOG_DEBUG);
2801
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2802
2803
        if ($result) {
2804
            $num = $this->db->num_rows($result);
2805
2806
            $form = '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
2807
2808
            if (!$num) {
2809
                $form .= '<option value="0">-- ' . $langs->trans("NoSupplierPriceDefinedForThisProduct") . ' --</option>';
2810
            } else {
2811
                require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php';
2812
                $form .= '<option value="0">&nbsp;</option>';
2813
2814
                $i = 0;
2815
                while ($i < $num) {
2816
                    $objp = $this->db->fetch_object($result);
2817
2818
                    $opt = '<option value="' . $objp->idprodfournprice . '"';
2819
                    //if there is only one supplier, preselect it
2820
                    if ($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) {
2821
                        $opt .= ' selected';
2822
                    }
2823
                    $opt .= '>' . $objp->name . ' - ' . $objp->ref_fourn . ' - ';
2824
2825
                    if (!empty(Globals::$conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2826
                        $prod_supplier = new ProductFournisseur($this->db);
2827
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2828
                        $prod_supplier->id = $productid;
2829
                        $prod_supplier->fourn_qty = $objp->quantity;
2830
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2831
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2832
                        $priceparser = new PriceParser($this->db);
2833
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2834
                        if ($price_result >= 0) {
2835
                            $objp->fprice = $price_result;
2836
                            if ($objp->quantity >= 1) {
2837
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2838
                            }
2839
                        }
2840
                    }
2841
                    if ($objp->quantity == 1) {
2842
                        $opt .= price($objp->fprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/";
2843
                    }
2844
2845
                    $opt .= $objp->quantity . ' ';
2846
2847
                    if ($objp->quantity == 1) {
2848
                        $opt .= $langs->trans("Unit");
2849
                    } else {
2850
                        $opt .= $langs->trans("Units");
2851
                    }
2852
                    if ($objp->quantity > 1) {
2853
                        $opt .= " - ";
2854
                        $opt .= price($objp->unitprice, 1, $langs, 0, 0, -1, Globals::$conf->currency) . "/" . $langs->trans("Unit");
2855
                    }
2856
                    if ($objp->duration)
2857
                        $opt .= " - " . $objp->duration;
2858
                    $opt .= "</option>\n";
2859
2860
                    $form .= $opt;
2861
                    $i++;
2862
                }
2863
            }
2864
2865
            $form .= '</select>';
2866
            $this->db->free($result);
2867
            return $form;
2868
        }
2869
        else {
2870
            DolUtils::dol_print_error($this->db);
2871
        }
2872
    }
2873
2874
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2875
    /**
2876
     *    Return list of delivery address
2877
     *
2878
     *    @param    string	$selected          	Id contact pre-selectionn
2879
     *    @param    int		$socid				Id of company
2880
     *    @param    string	$htmlname          	Name of HTML field
2881
     *    @param    int		$showempty         	Add an empty field
2882
     *    @return	integer|null
2883
     */
2884
    function select_address($selected, $socid, $htmlname = 'address_id', $showempty = 0)
2885
    {
2886
        // phpcs:enable
2887
        // looking for users
2888
        $sql = "SELECT a.rowid, a.label";
2889
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_address as a";
2890
        $sql .= " WHERE a.fk_soc = " . $socid;
2891
        $sql .= " ORDER BY a.label ASC";
2892
2893
        dol_syslog(get_class($this) . "::select_address", LOG_DEBUG);
2894
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2895
        if ($resql) {
2896
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
2897
            if ($showempty)
2898
                print '<option value="0">&nbsp;</option>';
2899
            $num = $this->db->num_rows($resql);
2900
            $i = 0;
2901
            if ($num) {
2902
                while ($i < $num) {
2903
                    $obj = $this->db->fetch_object($resql);
2904
2905
                    if ($selected && $selected == $obj->rowid) {
2906
                        print '<option value="' . $obj->rowid . '" selected>' . $obj->label . '</option>';
2907
                    } else {
2908
                        print '<option value="' . $obj->rowid . '">' . $obj->label . '</option>';
2909
                    }
2910
                    $i++;
2911
                }
2912
            }
2913
            print '</select>';
2914
            return $num;
2915
        } else {
2916
            DolUtils::dol_print_error($this->db);
2917
        }
2918
    }
2919
2920
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2921
    /**
2922
     *      Load into cache list of payment terms
2923
     *
2924
     *      @return     int             Nb of lines loaded, <0 if KO
2925
     */
2926
    function load_cache_conditions_paiements()
2927
    {
2928
        // phpcs:enable
2929
        global $langs;
2930
2931
        $num = count($this->cache_conditions_paiements);
2932
        if ($num > 0)
2933
            return 0;    // Cache already loaded
2934
2935
        dol_syslog(__METHOD__, LOG_DEBUG);
2936
2937
        $sql = "SELECT rowid, code, libelle as label";
2938
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_payment_term';
2939
        $sql .= " WHERE entity IN (" . getEntity('c_payment_term') . ")";
2940
        $sql .= " AND active > 0";
2941
        $sql .= " ORDER BY sortorder";
2942
2943
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2944
        if ($resql) {
2945
            $num = $this->db->num_rows($resql);
2946
            $i = 0;
2947
            while ($i < $num) {
2948
                $obj = $this->db->fetch_object($resql);
2949
2950
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2951
                $label = ($langs->trans("PaymentConditionShort" . $obj->code) != ("PaymentConditionShort" . $obj->code) ? $langs->trans("PaymentConditionShort" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
2952
                $this->cache_conditions_paiements[$obj->rowid]['code'] = $obj->code;
2953
                $this->cache_conditions_paiements[$obj->rowid]['label'] = $label;
2954
                $i++;
2955
            }
2956
2957
            //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1);		// We use the field sortorder of table
2958
2959
            return $num;
2960
        } else {
2961
            DolUtils::dol_print_error($this->db);
2962
            return -1;
2963
        }
2964
    }
2965
2966
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
2967
    /**
2968
     *      Charge dans cache la liste des délais de livraison possibles
2969
     *
2970
     *      @return     int             Nb of lines loaded, <0 if KO
2971
     */
2972
    function load_cache_availability()
2973
    {
2974
        // phpcs:enable
2975
        global $langs;
2976
2977
        $num = count($this->cache_availability);
2978
        if ($num > 0)
2979
            return 0;    // Cache already loaded
2980
2981
        dol_syslog(__METHOD__, LOG_DEBUG);
2982
2983
        $langs->load('propal');
2984
2985
        $sql = "SELECT rowid, code, label";
2986
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_availability';
2987
        $sql .= " WHERE active > 0";
2988
2989
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
2990
        if ($resql) {
2991
            $num = $this->db->num_rows($resql);
2992
            $i = 0;
2993
            while ($i < $num) {
2994
                $obj = $this->db->fetch_object($resql);
2995
2996
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2997
                $label = ($langs->trans("AvailabilityType" . $obj->code) != ("AvailabilityType" . $obj->code) ? $langs->trans("AvailabilityType" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
2998
                $this->cache_availability[$obj->rowid]['code'] = $obj->code;
2999
                $this->cache_availability[$obj->rowid]['label'] = $label;
3000
                $i++;
3001
            }
3002
3003
            $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1);
3004
3005
            return $num;
3006
        } else {
3007
            DolUtils::dol_print_error($this->db);
3008
            return -1;
3009
        }
3010
    }
3011
3012
    /**
3013
     *      Retourne la liste des types de delais de livraison possibles
3014
     *
3015
     *      @param	int		$selected        Id du type de delais pre-selectionne
3016
     *      @param  string	$htmlname        Nom de la zone select
3017
     *      @param  string	$filtertype      To add a filter
3018
     * 		@param	int		$addempty		Add empty entry
3019
     * 		@return	void
3020
     */
3021
    function selectAvailabilityDelay($selected = '', $htmlname = 'availid', $filtertype = '', $addempty = 0)
3022
    {
3023
        global $langs, $user;
3024
3025
        $this->load_cache_availability();
3026
3027
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
3028
3029
        print '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
3030
        if ($addempty)
3031
            print '<option value="0">&nbsp;</option>';
3032
        foreach ($this->cache_availability as $id => $arrayavailability) {
3033
            if ($selected == $id) {
3034
                print '<option value="' . $id . '" selected>';
3035
            } else {
3036
                print '<option value="' . $id . '">';
3037
            }
3038
            print $arrayavailability['label'];
3039
            print '</option>';
3040
        }
3041
        print '</select>';
3042
        if ($user->admin)
3043
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3044
    }
3045
3046
    /**
3047
     *      Load into cache cache_demand_reason, array of input reasons
3048
     *
3049
     *      @return     int             Nb of lines loaded, <0 if KO
3050
     */
3051
    function loadCacheInputReason()
3052
    {
3053
        global $langs;
3054
3055
        $num = count($this->cache_demand_reason);
3056
        if ($num > 0)
3057
            return 0;    // Cache already loaded
3058
3059
        $sql = "SELECT rowid, code, label";
3060
        $sql .= " FROM " . MAIN_DB_PREFIX . 'c_input_reason';
3061
        $sql .= " WHERE active > 0";
3062
3063
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3064
        if ($resql) {
3065
            $num = $this->db->num_rows($resql);
3066
            $i = 0;
3067
            $tmparray = array();
3068
            while ($i < $num) {
3069
                $obj = $this->db->fetch_object($resql);
3070
3071
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
3072
                $label = ($obj->label != '-' ? $obj->label : '');
3073
                if ($langs->trans("DemandReasonType" . $obj->code) != ("DemandReasonType" . $obj->code))
3074
                    $label = $langs->trans("DemandReasonType" . $obj->code); // So translation key DemandReasonTypeSRC_XXX will work
3075
                if ($langs->trans($obj->code) != $obj->code)
3076
                    $label = $langs->trans($obj->code);                // So translation key SRC_XXX will work
3077
3078
                $tmparray[$obj->rowid]['id'] = $obj->rowid;
3079
                $tmparray[$obj->rowid]['code'] = $obj->code;
3080
                $tmparray[$obj->rowid]['label'] = $label;
3081
                $i++;
3082
            }
3083
3084
            $this->cache_demand_reason = dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1);
3085
3086
            unset($tmparray);
3087
            return $num;
3088
        }
3089
        else {
3090
            DolUtils::dol_print_error($this->db);
3091
            return -1;
3092
        }
3093
    }
3094
3095
    /**
3096
     * 	Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
3097
     *  List found into table c_input_reason loaded by loadCacheInputReason
3098
     *
3099
     *  @param	int		$selected        Id or code of type origin to select by default
3100
     *  @param  string	$htmlname        Nom de la zone select
3101
     *  @param  string	$exclude         To exclude a code value (Example: SRC_PROP)
3102
     * 	@param	int		$addempty		 Add an empty entry
3103
     * 	@return	void
3104
     */
3105
    function selectInputReason($selected = '', $htmlname = 'demandreasonid', $exclude = '', $addempty = 0)
3106
    {
3107
        global $langs, $user;
3108
3109
        $this->loadCacheInputReason();
3110
3111
        print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
3112
        if ($addempty)
3113
            print '<option value="0"' . (empty($selected) ? ' selected' : '') . '>&nbsp;</option>';
3114
        foreach ($this->cache_demand_reason as $id => $arraydemandreason) {
3115
            if ($arraydemandreason['code'] == $exclude)
3116
                continue;
3117
3118
            if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code'])) {
3119
                print '<option value="' . $arraydemandreason['id'] . '" selected>';
3120
            } else {
3121
                print '<option value="' . $arraydemandreason['id'] . '">';
3122
            }
3123
            $label = $arraydemandreason['label']; // Translation of label was already done into the ->loadCacheInputReason
3124
            print $langs->trans($label);
3125
            print '</option>';
3126
        }
3127
        print '</select>';
3128
        if ($user->admin)
3129
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3130
    }
3131
3132
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3133
    /**
3134
     *      Charge dans cache la liste des types de paiements possibles
3135
     *
3136
     *      @return     int                 Nb of lines loaded, <0 if KO
3137
     */
3138
    function load_cache_types_paiements()
3139
    {
3140
        // phpcs:enable
3141
        global $langs;
3142
3143
        $num = count($this->cache_types_paiements);
3144
        if ($num > 0)
3145
            return $num;    // Cache already loaded
3146
3147
        dol_syslog(__METHOD__, LOG_DEBUG);
3148
3149
        $this->cache_types_paiements = array();
3150
3151
        $sql = "SELECT id, code, libelle as label, type, active";
3152
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_paiement";
3153
        $sql .= " WHERE entity IN (" . getEntity('c_paiement') . ")";
3154
        //if ($active >= 0) $sql.= " AND active = ".$active;
3155
3156
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3157
        if ($resql) {
3158
            $num = $this->db->num_rows($resql);
3159
            $i = 0;
3160
            while ($i < $num) {
3161
                $obj = $this->db->fetch_object($resql);
3162
3163
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
3164
                $label = ($langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) != ("PaymentTypeShort" . $obj->code) ? $langs->transnoentitiesnoconv("PaymentTypeShort" . $obj->code) : ($obj->label != '-' ? $obj->label : ''));
3165
                $this->cache_types_paiements[$obj->id]['id'] = $obj->id;
3166
                $this->cache_types_paiements[$obj->id]['code'] = $obj->code;
3167
                $this->cache_types_paiements[$obj->id]['label'] = $label;
3168
                $this->cache_types_paiements[$obj->id]['type'] = $obj->type;
3169
                $this->cache_types_paiements[$obj->id]['active'] = $obj->active;
3170
                $i++;
3171
            }
3172
3173
            $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1);
3174
3175
            return $num;
3176
        } else {
3177
            DolUtils::dol_print_error($this->db);
3178
            return -1;
3179
        }
3180
    }
3181
3182
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3183
    /**
3184
     *      Return list of payment modes.
3185
     *      Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
3186
     *      See instead to force the default value by the caller.
3187
     *
3188
     *      @param	int		$selected		Id of payment term to preselect by default
3189
     *      @param	string	$htmlname		Nom de la zone select
3190
     *      @param	int		$filtertype		Not used
3191
     * 		@param	int		$addempty		Add an empty entry
3192
     * 		@param	int		$noinfoadmin		0=Add admin info, 1=Disable admin info
3193
     * 		@param	string	$morecss			Add more CSS on select tag
3194
     * 		@return	void
3195
     */
3196
    function select_conditions_paiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '')
3197
    {
3198
        // phpcs:enable
3199
        global $langs, $user, $conf;
3200
3201
        dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
3202
3203
        $this->load_cache_conditions_paiements();
3204
3205
        // Set default value if not already set by caller
3206
        if (empty($selected) && !empty(Globals::$conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID))
3207
            $selected = Globals::$conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID;
3208
3209
        print '<select id="' . $htmlname . '" class="flat selectpaymentterms' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '">';
3210
        if ($addempty)
3211
            print '<option value="0">&nbsp;</option>';
3212
        foreach ($this->cache_conditions_paiements as $id => $arrayconditions) {
3213
            if ($selected == $id) {
3214
                print '<option value="' . $id . '" selected>';
3215
            } else {
3216
                print '<option value="' . $id . '">';
3217
            }
3218
            print $arrayconditions['label'];
3219
            print '</option>';
3220
        }
3221
        print '</select>';
3222
        if ($user->admin && empty($noinfoadmin))
3223
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3224
    }
3225
3226
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3227
    /**
3228
     *      Return list of payment methods
3229
     *
3230
     *      @param	string	$selected       Id du mode de paiement pre-selectionne
3231
     *      @param  string	$htmlname       Nom de la zone select
3232
     *      @param  string	$filtertype     To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz))
3233
     *      @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
3234
     *      @param  int		$empty			1=peut etre vide, 0 sinon
3235
     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
3236
     *      @param  int		$maxlength      Max length of label
3237
     *      @param  int     $active         Active or not, -1 = all
3238
     *      @param  string  $morecss        Add more CSS on select tag
3239
     * 		@return	void
3240
     */
3241
    function select_types_paiements($selected = '', $htmlname = 'paiementtype', $filtertype = '', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss = '')
3242
    {
3243
        // phpcs:enable
3244
        global $langs, $user;
3245
3246
        dol_syslog(__METHOD__ . " " . $selected . ", " . $htmlname . ", " . $filtertype . ", " . $format, LOG_DEBUG);
3247
3248
        $filterarray = array();
3249
        if ($filtertype == 'CRDT')
3250
            $filterarray = array(0, 2, 3);
3251
        elseif ($filtertype == 'DBIT')
3252
            $filterarray = array(1, 2, 3);
3253
        elseif ($filtertype != '' && $filtertype != '-1')
3254
            $filterarray = explode(',', $filtertype);
3255
3256
        $this->load_cache_types_paiements();
3257
3258
        print '<select id="select' . $htmlname . '" class="flat selectpaymenttypes' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '">';
3259
        if ($empty)
3260
            print '<option value="">&nbsp;</option>';
3261
        foreach ($this->cache_types_paiements as $id => $arraytypes) {
3262
            // If not good status
3263
            if ($active >= 0 && $arraytypes['active'] != $active)
3264
                continue;
3265
3266
            // On passe si on a demande de filtrer sur des modes de paiments particuliers
3267
            if (count($filterarray) && !in_array($arraytypes['type'], $filterarray))
3268
                continue;
3269
3270
            // We discard empty line if showempty is on because an empty line has already been output.
3271
            if ($empty && empty($arraytypes['code']))
3272
                continue;
3273
3274
            if ($format == 0)
3275
                print '<option value="' . $id . '"';
3276
            elseif ($format == 1)
3277
                print '<option value="' . $arraytypes['code'] . '"';
3278
            elseif ($format == 2)
3279
                print '<option value="' . $arraytypes['code'] . '"';
3280
            elseif ($format == 3)
3281
                print '<option value="' . $id . '"';
3282
            // Si selected est text, on compare avec code, sinon avec id
3283
            if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code'])
3284
                print ' selected';
3285
            elseif ($selected == $id)
3286
                print ' selected';
3287
            print '>';
3288
            if ($format == 0)
3289
                $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
3290
            elseif ($format == 1)
3291
                $value = $arraytypes['code'];
3292
            elseif ($format == 2)
3293
                $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
3294
            elseif ($format == 3)
3295
                $value = $arraytypes['code'];
3296
            print $value ? $value : '&nbsp;';
3297
            print '</option>';
3298
        }
3299
        print '</select>';
3300
        if ($user->admin && !$noadmininfo)
3301
            print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3302
    }
3303
3304
    /**
3305
     *  Selection HT or TTC
3306
     *
3307
     *  @param	string	$selected       Id pre-selectionne
3308
     *  @param  string	$htmlname       Nom de la zone select
3309
     * 	@return	string					Code of HTML select to chose tax or not
3310
     */
3311
    function selectPriceBaseType($selected = '', $htmlname = 'price_base_type')
3312
    {
3313
        global $langs;
3314
3315
        $return = '';
3316
3317
        $return .= '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
3318
        $options = array(
3319
            'HT' => $langs->trans("HT"),
3320
            'TTC' => $langs->trans("TTC")
3321
        );
3322
        foreach ($options as $id => $value) {
3323
            if ($selected == $id) {
3324
                $return .= '<option value="' . $id . '" selected>' . $value;
3325
            } else {
3326
                $return .= '<option value="' . $id . '">' . $value;
3327
            }
3328
            $return .= '</option>';
3329
        }
3330
        $return .= '</select>';
3331
3332
        return $return;
3333
    }
3334
3335
    /**
3336
     *  Return a HTML select list of shipping mode
3337
     *
3338
     *  @param	string	$selected          Id shipping mode pre-selected
3339
     *  @param  string	$htmlname          Name of select zone
3340
     *  @param  string	$filtre            To filter list
3341
     *  @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.
3342
     *  @param  string	$moreattrib        To add more attribute on select
3343
     * 	@return	void
3344
     */
3345
    function selectShippingMethod($selected = '', $htmlname = 'shipping_method_id', $filtre = '', $useempty = 0, $moreattrib = '')
3346
    {
3347
        global $langs, $conf, $user;
3348
3349
        $langs->load("admin");
3350
        $langs->load("deliveries");
3351
3352
        $sql = "SELECT rowid, code, libelle as label";
3353
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_shipment_mode";
3354
        $sql .= " WHERE active > 0";
3355
        if ($filtre)
3356
            $sql .= " AND " . $filtre;
3357
        $sql .= " ORDER BY libelle ASC";
3358
3359
        dol_syslog(get_class($this) . "::selectShippingMode", LOG_DEBUG);
3360
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3361
        if ($result) {
3362
            $num = $this->db->num_rows($result);
3363
            $i = 0;
3364
            if ($num) {
3365
                print '<select id="select' . $htmlname . '" class="flat selectshippingmethod" name="' . $htmlname . '"' . ($moreattrib ? ' ' . $moreattrib : '') . '>';
3366
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3367
                    print '<option value="-1">&nbsp;</option>';
3368
                }
3369
                while ($i < $num) {
3370
                    $obj = $this->db->fetch_object($result);
3371
                    if ($selected == $obj->rowid) {
3372
                        print '<option value="' . $obj->rowid . '" selected>';
3373
                    } else {
3374
                        print '<option value="' . $obj->rowid . '">';
3375
                    }
3376
                    print ($langs->trans("SendingMethod" . strtoupper($obj->code)) != "SendingMethod" . strtoupper($obj->code)) ? $langs->trans("SendingMethod" . strtoupper($obj->code)) : $obj->label;
3377
                    print '</option>';
3378
                    $i++;
3379
                }
3380
                print "</select>";
3381
                if ($user->admin)
3382
                    print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
3383
            } else {
3384
                print $langs->trans("NoShippingMethodDefined");
3385
            }
3386
        } else {
3387
            DolUtils::dol_print_error($this->db);
3388
        }
3389
    }
3390
3391
    /**
3392
     *    Display form to select shipping mode
3393
     *
3394
     *    @param	string	$page        Page
3395
     *    @param    int		$selected    Id of shipping mode
3396
     *    @param    string	$htmlname    Name of select html field
3397
     *    @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.
3398
     *    @return	void
3399
     */
3400
    function formSelectShippingMethod($page, $selected = '', $htmlname = 'shipping_method_id', $addempty = 0)
3401
    {
3402
        global $langs, $db;
3403
3404
        $langs->load("deliveries");
3405
3406
        if ($htmlname != "none") {
3407
            print '<form method="POST" action="' . $page . '">';
3408
            print '<input type="hidden" name="action" value="setshippingmethod">';
3409
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
3410
            $this->selectShippingMethod($selected, $htmlname, '', $addempty);
3411
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
3412
            print '</form>';
3413
        } else {
3414
            if ($selected) {
3415
                $code = $langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code');
3416
                print $langs->trans("SendingMethod" . strtoupper($code));
3417
            } else {
3418
                print "&nbsp;";
3419
            }
3420
        }
3421
    }
3422
3423
    /**
3424
     * Creates HTML last in cycle situation invoices selector
3425
     *
3426
     * @param     string  $selected   		Preselected ID
3427
     * @param     int     $socid      		Company ID
3428
     *
3429
     * @return    string                     HTML select
3430
     */
3431
    function selectSituationInvoices($selected = '', $socid = 0)
3432
    {
3433
        global $langs;
3434
3435
        $langs->load('bills');
3436
3437
        $opt = '<option value ="" selected></option>';
3438
        $sql = 'SELECT rowid, ref, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1';
3439
        $sql .= ' ORDER by situation_cycle_ref, situation_counter desc';
3440
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3441
        if ($resql && $this->db->num_rows($resql) > 0) {
3442
            // Last seen cycle
3443
            $ref = 0;
3444
            while ($obj = $this->db->fetch_object($resql)) {
3445
                //Same company ?
3446
                if ($socid == $obj->fk_soc) {
3447
                    //Same cycle ?
3448
                    if ($obj->situation_cycle_ref != $ref) {
3449
                        // Just seen this cycle
3450
                        $ref = $obj->situation_cycle_ref;
3451
                        //not final ?
3452
                        if ($obj->situation_final != 1) {
3453
                            //Not prov?
3454
                            if (substr($obj->ref, 1, 4) != 'PROV') {
3455
                                if ($selected == $obj->rowid) {
3456
                                    $opt .= '<option value="' . $obj->rowid . '" selected>' . $obj->ref . '</option>';
3457
                                } else {
3458
                                    $opt .= '<option value="' . $obj->rowid . '">' . $obj->ref . '</option>';
3459
                                }
3460
                            }
3461
                        }
3462
                    }
3463
                }
3464
            }
3465
        } else {
3466
            dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
3467
        }
3468
        if ($opt == '<option value ="" selected></option>') {
3469
            $opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>';
3470
        }
3471
        return $opt;
3472
    }
3473
3474
    /**
3475
     *      Creates HTML units selector (code => label)
3476
     *
3477
     *      @param	string	$selected       Preselected Unit ID
3478
     *      @param  string	$htmlname       Select name
3479
     *      @param	int		$showempty		Add a nempty line
3480
     * 		@return	string                  HTML select
3481
     */
3482
    function selectUnits($selected = '', $htmlname = 'units', $showempty = 0)
3483
    {
3484
        global $langs;
3485
3486
        $langs->load('products');
3487
3488
        $return = '<select class="flat" id="' . $htmlname . '" name="' . $htmlname . '">';
3489
3490
        $sql = 'SELECT rowid, label, code from ' . MAIN_DB_PREFIX . 'c_units';
3491
        $sql .= ' WHERE active > 0';
3492
3493
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3494
        if ($resql && $this->db->num_rows($resql) > 0) {
3495
            if ($showempty)
3496
                $return .= '<option value="none"></option>';
3497
3498
            while ($res = $this->db->fetch_object($resql)) {
3499
                $unitLabel = $res->label;
3500
                if (!empty($langs->tab_translate['unit' . $res->code])) { // check if Translation is available before
3501
                    $unitLabel = $langs->trans('unit' . $res->code) != $res->label ? $langs->trans('unit' . $res->code) : $res->label;
3502
                }
3503
3504
                if ($selected == $res->rowid) {
3505
                    $return .= '<option value="' . $res->rowid . '" selected>' . $unitLabel . '</option>';
3506
                } else {
3507
                    $return .= '<option value="' . $res->rowid . '">' . $unitLabel . '</option>';
3508
                }
3509
            }
3510
            $return .= '</select>';
3511
        }
3512
        return $return;
3513
    }
3514
3515
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3516
    /**
3517
     *  Return a HTML select list of bank accounts
3518
     *
3519
     *  @param	string	$selected           Id account pre-selected
3520
     *  @param  string	$htmlname           Name of select zone
3521
     *  @param  int		$statut             Status of searched accounts (0=open, 1=closed, 2=both)
3522
     *  @param  string	$filtre             To filter list
3523
     *  @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.
3524
     *  @param  string	$moreattrib         To add more attribute on select
3525
     *  @param	int		$showcurrency		Show currency in label
3526
     * 	@return	int							<0 if error, Num of bank account found if OK (0, 1, 2, ...)
3527
     */
3528
    function select_comptes($selected = '', $htmlname = 'accountid', $statut = 0, $filtre = '', $useempty = 0, $moreattrib = '', $showcurrency = 0)
3529
    {
3530
        // phpcs:enable
3531
        global $langs, $conf;
3532
3533
        $langs->load("admin");
3534
        $num = 0;
3535
3536
        $sql = "SELECT rowid, label, bank, clos as status, currency_code";
3537
        $sql .= " FROM " . MAIN_DB_PREFIX . "bank_account";
3538
        $sql .= " WHERE entity IN (" . getEntity('bank_account') . ")";
3539
        if ($statut != 2)
3540
            $sql .= " AND clos = '" . $statut . "'";
3541
        if ($filtre)
3542
            $sql .= " AND " . $filtre;
3543
        $sql .= " ORDER BY label";
3544
3545
        dol_syslog(get_class($this) . "::select_comptes", LOG_DEBUG);
3546
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3547
        if ($result) {
3548
            $num = $this->db->num_rows($result);
3549
            $i = 0;
3550
            if ($num) {
3551
                print '<select id="select' . $htmlname . '" class="flat selectbankaccount" name="' . $htmlname . '"' . ($moreattrib ? ' ' . $moreattrib : '') . '>';
3552
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3553
                    print '<option value="-1">&nbsp;</option>';
3554
                }
3555
3556
                while ($i < $num) {
3557
                    $obj = $this->db->fetch_object($result);
3558
                    if ($selected == $obj->rowid) {
3559
                        print '<option value="' . $obj->rowid . '" selected>';
3560
                    } else {
3561
                        print '<option value="' . $obj->rowid . '">';
3562
                    }
3563
                    print trim($obj->label);
3564
                    if ($showcurrency)
3565
                        print ' (' . $obj->currency_code . ')';
3566
                    if ($statut == 2 && $obj->status == 1)
3567
                        print ' (' . $langs->trans("Closed") . ')';
3568
                    print '</option>';
3569
                    $i++;
3570
                }
3571
                print "</select>";
3572
            }
3573
            else {
3574
                if ($statut == 0)
3575
                    print '<span class="opacitymedium">' . $langs->trans("NoActiveBankAccountDefined") . '</span>';
3576
                else
3577
                    print '<span class="opacitymedium">' . $langs->trans("NoBankAccountFound") . '</span>';
3578
            }
3579
        }
3580
        else {
3581
            DolUtils::dol_print_error($this->db);
3582
        }
3583
3584
        return $num;
3585
    }
3586
3587
    /**
3588
     *    Display form to select bank account
3589
     *
3590
     *    @param	string	$page        Page
3591
     *    @param    int		$selected    Id of bank account
3592
     *    @param    string	$htmlname    Name of select html field
3593
     *    @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.
3594
     *    @return	void
3595
     */
3596
    function formSelectAccount($page, $selected = '', $htmlname = 'fk_account', $addempty = 0)
3597
    {
3598
        global $langs;
3599
        if ($htmlname != "none") {
3600
            print '<form method="POST" action="' . $page . '">';
3601
            print '<input type="hidden" name="action" value="setbankaccount">';
3602
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
3603
            $nbaccountfound = $this->select_comptes($selected, $htmlname, 0, '', $addempty);
3604
            if ($nbaccountfound > 0)
3605
                print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
3606
            print '</form>';
3607
        } else {
3608
3609
            $langs->load('banks');
3610
3611
            if ($selected) {
3612
                require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php';
3613
                $bankstatic = new Account($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3614
                $result = $bankstatic->fetch($selected);
3615
                if ($result)
3616
                    print $bankstatic->getNomUrl(1);
3617
            } else {
3618
                print "&nbsp;";
3619
            }
3620
        }
3621
    }
3622
3623
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3624
    /**
3625
     *    Return list of categories having choosed type
3626
     *
3627
     *    @param	string|int	$type				Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated.
3628
     *    @param    string		$selected    		Id of category preselected or 'auto' (autoselect category if there is only one element)
3629
     *    @param    string		$htmlname			HTML field name
3630
     *    @param    int			$maxlength      	Maximum length for labels
3631
     *    @param    int			$excludeafterid 	Exclude all categories after this leaf in category tree.
3632
     *    @param	int			$outputmode			0=HTML select string, 1=Array
3633
     *    @return	string
3634
     *    @see select_categories
3635
     */
3636
    function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $excludeafterid = 0, $outputmode = 0)
3637
    {
3638
        // phpcs:enable
3639
        global $conf, $langs;
3640
        $langs->load("categories");
3641
3642
        include_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
3643
3644
        // For backward compatibility
3645
        if (is_numeric($type)) {
3646
            dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING);
3647
        }
3648
3649
        if ($type === Categorie::TYPE_BANK_LINE) {
3650
            // TODO Move this into common category feature
3651
            $categids = array();
3652
            $sql = "SELECT c.label, c.rowid";
3653
            $sql .= " FROM " . MAIN_DB_PREFIX . "bank_categ as c";
3654
            $sql .= " WHERE entity = " . Globals::$conf->entity;
3655
            $sql .= " ORDER BY c.label";
3656
            $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
3657
            if ($result) {
3658
                $num = $this->db->num_rows($result);
3659
                $i = 0;
3660
                while ($i < $num) {
3661
                    $objp = $this->db->fetch_object($result);
3662
                    if ($objp)
3663
                        $cate_arbo[$objp->rowid] = array('id' => $objp->rowid, 'fulllabel' => $objp->label);
3664
                    $i++;
3665
                }
3666
                $this->db->free($result);
3667
            } else
3668
                DolUtils::dol_print_error($this->db);
3669
        }
3670
        else {
3671
            $cat = new Categorie($this->db);
3672
            $cate_arbo = $cat->get_full_arbo($type, $excludeafterid);
3673
        }
3674
3675
        $output = '<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
3676
        $outarray = array();
3677
        if (is_array($cate_arbo)) {
3678
            if (!count($cate_arbo))
3679
                $output .= '<option value="-1" disabled>' . $langs->trans("NoCategoriesDefined") . '</option>';
3680
            else {
3681
                $output .= '<option value="-1">&nbsp;</option>';
3682
                foreach ($cate_arbo as $key => $value) {
3683
                    if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1)) {
3684
                        $add = 'selected ';
3685
                    } else {
3686
                        $add = '';
3687
                    }
3688
                    $output .= '<option ' . $add . 'value="' . $cate_arbo[$key]['id'] . '">' . dol_trunc($cate_arbo[$key]['fulllabel'], $maxlength, 'middle') . '</option>';
3689
3690
                    $outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel'];
3691
                }
3692
            }
3693
        }
3694
        $output .= '</select>';
3695
        $output .= "\n";
3696
3697
        if ($outputmode)
3698
            return $outarray;
3699
        return $output;
3700
    }
3701
3702
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
3703
    /**
3704
     *     Show a confirmation HTML form or AJAX popup
3705
     *
3706
     *     @param	string		$page        	   	Url of page to call if confirmation is OK
3707
     *     @param	string		$title       	   	Title
3708
     *     @param	string		$question    	   	Question
3709
     *     @param 	string		$action      	   	Action
3710
     * 	   @param	array		$formquestion	   	An array with forms complementary inputs
3711
     * 	   @param	string		$selectedchoice		"" or "no" or "yes"
3712
     * 	   @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
3713
     *     @param	int			$height          	Force height of box
3714
     *     @param	int			$width				Force width of box
3715
     *     @return 	void
3716
     *     @deprecated
3717
     *     @see formconfirm()
3718
     */
3719
    function form_confirm($page, $title, $question, $action, $formquestion = '', $selectedchoice = "", $useajax = 0, $height = 170, $width = 500)
3720
    {
3721
        // phpcs:enable
3722
        dol_syslog(__METHOD__ . ': using form_confirm is deprecated. Use formconfim instead.', LOG_WARNING);
3723
        print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
3724
    }
3725
3726
    /**
3727
     *     Show a confirmation HTML form or AJAX popup.
3728
     *     Easiest way to use this is with useajax=1.
3729
     *     If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters)
3730
     *     just after calling this method. For example:
3731
     *       print '<script type="text/javascript">'."\n";
3732
     *       print 'jQuery(document).ready(function() {'."\n";
3733
     *       print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n";
3734
     *       print '});'."\n";
3735
     *       print '</script>'."\n";
3736
     *
3737
     *     @param  	string		$page        	   	Url of page to call if confirmation is OK. Can contains paramaters (param 'action' and 'confirm' will be reformated)
3738
     *     @param	string		$title       	   	Title
3739
     *     @param	string		$question    	   	Question
3740
     *     @param 	string		$action      	   	Action
3741
     * 	   @param  	array		$formquestion	   	An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , ))
3742
     * 												type can be 'hidden', 'text', 'password', 'checkbox', 'radio', 'date', 'morecss', ...
3743
     * 	   @param  	string		$selectedchoice  	'' or 'no', or 'yes' or '1' or '0'
3744
     * 	   @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
3745
     *     @param  	int			$height          	Force height of box
3746
     *     @param	int			$width				Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones.
3747
     *     @param	int			$disableformtag		1=Disable form tag. Can be used if we are already inside a <form> section.
3748
     *     @return 	string      	    			HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form
3749
     */
3750
    function formconfirm($page, $title, $question, $action, $formquestion = '', $selectedchoice = '', $useajax = 0, $height = 210, $width = 500, $disableformtag = 0)
3751
    {
3752
        global $langs, $conf;
3753
        global $useglobalvars;
3754
3755
        $more = '';
3756
        $formconfirm = '';
3757
        $inputok = array();
3758
        $inputko = array();
3759
3760
        // Clean parameters
3761
        $newselectedchoice = empty($selectedchoice) ? "no" : $selectedchoice;
3762
        if (Globals::$conf->browser->layout == 'phone')
3763
            $width = '95%';
3764
3765
        if (is_array($formquestion) && !empty($formquestion)) {
3766
            // First add hidden fields and value
3767
            foreach ($formquestion as $key => $input) {
3768
                if (is_array($input) && !empty($input)) {
3769
                    if ($input['type'] == 'hidden') {
3770
                        $more .= '<input type="hidden" id="' . $input['name'] . '" name="' . $input['name'] . '" value="' . DolUtils::dol_escape_htmltag($input['value']) . '">' . "\n";
3771
                    }
3772
                }
3773
            }
3774
3775
            // Now add questions
3776
            $more .= '<table class="paddingtopbottomonly" width="100%">' . "\n";
3777
            if (!empty($formquestion['text']))
3778
                $more .= '<tr><td colspan="2">' . $formquestion['text'] . '</td></tr>' . "\n";
3779
            foreach ($formquestion as $key => $input) {
3780
                if (is_array($input) && !empty($input)) {
3781
                    $size = (!empty($input['size']) ? ' size="' . $input['size'] . '"' : '');
3782
                    $moreattr = (!empty($input['moreattr']) ? ' ' . $input['moreattr'] : '');
3783
                    $morecss = (!empty($input['morecss']) ? ' ' . $input['morecss'] : '');
3784
3785
                    if ($input['type'] == 'text') {
3786
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td><td align="left"><input type="text" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $size . ' value="' . $input['value'] . '"' . $moreattr . ' /></td></tr>' . "\n";
3787
                    } elseif ($input['type'] == 'password') {
3788
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td><td align="left"><input type="password" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $size . ' value="' . $input['value'] . '"' . $moreattr . ' /></td></tr>' . "\n";
3789
                    } elseif ($input['type'] == 'select') {
3790
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>';
3791
                        if (!empty($input['label']))
3792
                            $more .= $input['label'] . '</td><td class="tdtop" align="left">';
3793
                        $more .= $this->selectarray($input['name'], $input['values'], $input['default'], 1, 0, 0, $moreattr, 0, 0, 0, '', $morecss);
3794
                        $more .= '</td></tr>' . "\n";
3795
                    }
3796
                    elseif ($input['type'] == 'checkbox') {
3797
                        $more .= '<tr>';
3798
                        $more .= '<td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . ' </td><td align="left">';
3799
                        $more .= '<input type="checkbox" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '"' . $moreattr;
3800
                        if (!is_bool($input['value']) && $input['value'] != 'false' && $input['value'] != '0')
3801
                            $more .= ' checked';
3802
                        if (is_bool($input['value']) && $input['value'])
3803
                            $more .= ' checked';
3804
                        if (isset($input['disabled']))
3805
                            $more .= ' disabled';
3806
                        $more .= ' /></td>';
3807
                        $more .= '</tr>' . "\n";
3808
                    }
3809
                    elseif ($input['type'] == 'radio') {
3810
                        $i = 0;
3811
                        foreach ($input['values'] as $selkey => $selval) {
3812
                            $more .= '<tr>';
3813
                            if ($i == 0)
3814
                                $more .= '<td' . (empty($input['tdclass']) ? ' class="tdtop"' : (' class="tdtop ' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td>';
3815
                            else
3816
                                $more .= '<td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>&nbsp;</td>';
3817
                            $more .= '<td><input type="radio" class="flat' . $morecss . '" id="' . $input['name'] . '" name="' . $input['name'] . '" value="' . $selkey . '"' . $moreattr;
3818
                            if ($input['disabled'])
3819
                                $more .= ' disabled';
3820
                            $more .= ' /> ';
3821
                            $more .= $selval;
3822
                            $more .= '</td></tr>' . "\n";
3823
                            $i++;
3824
                        }
3825
                    }
3826
                    elseif ($input['type'] == 'date') {
3827
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>' . $input['label'] . '</td>';
3828
                        $more .= '<td align="left">';
3829
                        $more .= $this->selectDate($input['value'], $input['name'], 0, 0, 0, '', 1, 0);
3830
                        $more .= '</td></tr>' . "\n";
3831
                        $formquestion[] = array('name' => $input['name'] . 'day');
3832
                        $formquestion[] = array('name' => $input['name'] . 'month');
3833
                        $formquestion[] = array('name' => $input['name'] . 'year');
3834
                        $formquestion[] = array('name' => $input['name'] . 'hour');
3835
                        $formquestion[] = array('name' => $input['name'] . 'min');
3836
                    } elseif ($input['type'] == 'other') {
3837
                        $more .= '<tr><td' . (empty($input['tdclass']) ? '' : (' class="' . $input['tdclass'] . '"')) . '>';
3838
                        if (!empty($input['label']))
3839
                            $more .= $input['label'] . '</td><td align="left">';
3840
                        $more .= $input['value'];
3841
                        $more .= '</td></tr>' . "\n";
3842
                    }
3843
3844
                    elseif ($input['type'] == 'onecolumn') {
3845
                        $more .= '<tr><td colspan="2" align="left">';
3846
                        $more .= $input['value'];
3847
                        $more .= '</td></tr>' . "\n";
3848
                    }
3849
                }
3850
            }
3851
            $more .= '</table>' . "\n";
3852
        }
3853
3854
        // JQUI method dialog is broken with jmobile, we use standard HTML.
3855
        // 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
3856
        // See page product/card.php for example
3857
        if (!empty(Globals::$conf->dol_use_jmobile))
3858
            $useajax = 0;
3859
        if (empty(Globals::$conf->use_javascript_ajax))
3860
            $useajax = 0;
3861
3862
        if ($useajax) {
3863
            $autoOpen = true;
3864
            $dialogconfirm = 'dialog-confirm';
3865
            $button = '';
3866
            if (!is_numeric($useajax)) {
3867
                $button = $useajax;
3868
                $useajax = 1;
3869
                $autoOpen = false;
3870
                $dialogconfirm .= '-' . $button;
3871
            }
3872
            $pageyes = $page . (preg_match('/\?/', $page) ? '&' : '?') . 'action=' . $action . '&confirm=yes';
3873
            $pageno = ($useajax == 2 ? $page . (preg_match('/\?/', $page) ? '&' : '?') . 'confirm=no' : '');
3874
            // Add input fields into list of fields to read during submit (inputok and inputko)
3875
            if (is_array($formquestion)) {
3876
                foreach ($formquestion as $key => $input) {
3877
                    //print "xx ".$key." rr ".is_array($input)."<br>\n";
3878
                    if (is_array($input) && isset($input['name']))
3879
                        array_push($inputok, $input['name']);
3880
                    if (isset($input['inputko']) && $input['inputko'] == 1)
3881
                        array_push($inputko, $input['name']);
3882
                }
3883
            }
3884
            // Show JQuery confirm box. Note that global var $useglobalvars is used inside this template
3885
            $formconfirm .= '<div id="' . $dialogconfirm . '" title="' . DolUtils::dol_escape_htmltag($title) . '" style="display: none;">';
3886
            if (!empty($more)) {
3887
                $formconfirm .= '<div class="confirmquestions">' . $more . '</div>';
3888
            }
3889
            $formconfirm .= ($question ? '<div class="confirmmessage">' . img_help('', '') . ' ' . $question . '</div>' : '');
3890
            $formconfirm .= '</div>' . "\n";
3891
3892
            $formconfirm .= "\n<!-- begin ajax formconfirm page=" . $page . " -->\n";
3893
            $formconfirm .= '<script type="text/javascript">' . "\n";
3894
            $formconfirm .= 'jQuery(document).ready(function() {
3895
            $(function() {
3896
            	$( "#' . $dialogconfirm . '" ).dialog(
3897
            	{
3898
                    autoOpen: ' . ($autoOpen ? "true" : "false") . ',';
3899
            if ($newselectedchoice == 'no') {
3900
                $formconfirm .= '
3901
						open: function() {
3902
            				$(this).parent().find("button.ui-button:eq(2)").focus();
3903
						},';
3904
            }
3905
            $formconfirm .= '
3906
                    resizable: false,
3907
                    height: "' . $height . '",
3908
                    width: "' . $width . '",
3909
                    modal: true,
3910
                    closeOnEscape: false,
3911
                    buttons: {
3912
                        "' . dol_escape_js($langs->transnoentities("Yes")) . '": function() {
3913
                        	var options="";
3914
                        	var inputok = ' . json_encode($inputok) . ';
3915
                         	var pageyes = "' . dol_escape_js(!empty($pageyes) ? $pageyes : '') . '";
3916
                         	if (inputok.length>0) {
3917
                         		$.each(inputok, function(i, inputname) {
3918
                         			var more = "";
3919
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3920
                         		    if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; }
3921
                         			var inputvalue = $("#" + inputname + more).val();
3922
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3923
                         			options += "&" + inputname + "=" + encodeURIComponent(inputvalue);
3924
                         		});
3925
                         	}
3926
                         	var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options;
3927
                         	//alert(urljump);
3928
            				if (pageyes.length > 0) { location.href = urljump; }
3929
                            $(this).dialog("close");
3930
                        },
3931
                        "' . dol_escape_js($langs->transnoentities("No")) . '": function() {
3932
                        	var options = "";
3933
                         	var inputko = ' . json_encode($inputko) . ';
3934
                         	var pageno="' . dol_escape_js(!empty($pageno) ? $pageno : '') . '";
3935
                         	if (inputko.length>0) {
3936
                         		$.each(inputko, function(i, inputname) {
3937
                         			var more = "";
3938
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3939
                         			var inputvalue = $("#" + inputname + more).val();
3940
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3941
                         			options += "&" + inputname + "=" + encodeURIComponent(inputvalue);
3942
                         		});
3943
                         	}
3944
                         	var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options;
3945
                         	//alert(urljump);
3946
            				if (pageno.length > 0) { location.href = urljump; }
3947
                            $(this).dialog("close");
3948
                        }
3949
                    }
3950
                }
3951
                );
3952
3953
            	var button = "' . $button . '";
3954
            	if (button.length > 0) {
3955
                	$( "#" + button ).click(function() {
3956
                		$("#' . $dialogconfirm . '").dialog("open");
3957
        			});
3958
                }
3959
            });
3960
            });
3961
            </script>';
3962
            $formconfirm .= "<!-- end ajax formconfirm -->\n";
3963
        } else {
3964
            $formconfirm .= "\n<!-- begin formconfirm page=" . $page . " -->\n";
3965
3966
            if (empty($disableformtag))
3967
                $formconfirm .= '<form method="POST" action="' . $page . '" class="notoptoleftroright">' . "\n";
3968
3969
            $formconfirm .= '<input type="hidden" name="action" value="' . $action . '">' . "\n";
3970
            if (empty($disableformtag))
3971
                $formconfirm .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">' . "\n";
3972
3973
            $formconfirm .= '<table width="100%" class="valid">' . "\n";
3974
3975
            // Line title
3976
            $formconfirm .= '<tr class="validtitre"><td class="validtitre" colspan="3">' . img_picto('', 'recent') . ' ' . $title . '</td></tr>' . "\n";
3977
3978
            // Line form fields
3979
            if ($more) {
3980
                $formconfirm .= '<tr class="valid"><td class="valid" colspan="3">' . "\n";
3981
                $formconfirm .= $more;
3982
                $formconfirm .= '</td></tr>' . "\n";
3983
            }
3984
3985
            // Line with question
3986
            $formconfirm .= '<tr class="valid">';
3987
            $formconfirm .= '<td class="valid">' . $question . '</td>';
3988
            $formconfirm .= '<td class="valid">';
3989
            $formconfirm .= $this->selectyesno("confirm", $newselectedchoice);
3990
            $formconfirm .= '</td>';
3991
            $formconfirm .= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="' . $langs->trans("Validate") . '"></td>';
3992
            $formconfirm .= '</tr>' . "\n";
3993
3994
            $formconfirm .= '</table>' . "\n";
3995
3996
            if (empty($disableformtag))
3997
                $formconfirm .= "</form>\n";
3998
            $formconfirm .= '<br>';
3999
4000
            $formconfirm .= "<!-- end formconfirm -->\n";
4001
        }
4002
4003
        return $formconfirm;
4004
    }
4005
4006
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4007
    /**
4008
     *    Show a form to select a project
4009
     *
4010
     *    @param	int		$page        		Page
4011
     *    @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)
4012
     *    @param    int		$selected    		Id pre-selected project
4013
     *    @param    string	$htmlname    		Name of select field
4014
     *    @param	int		$discard_closed		Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable)
4015
     *    @param	int		$maxlength			Max length
4016
     *    @param	int		$forcefocus			Force focus on field (works with javascript only)
4017
     *    @param    int     $nooutput           No print is done. String is returned.
4018
     *    @return	string                      Return html content
4019
     */
4020
    function form_project($page, $socid, $selected = '', $htmlname = 'projectid', $discard_closed = 0, $maxlength = 20, $forcefocus = 0, $nooutput = 0)
4021
    {
4022
        // phpcs:enable
4023
        global $langs;
4024
4025
        require_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
4026
        require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
4027
4028
        $out = '';
4029
4030
        $formproject = new FormProjets($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4031
4032
        $langs->load("project");
4033
        if ($htmlname != "none") {
4034
            $out .= "\n";
4035
            $out .= '<form method="post" action="' . $page . '">';
4036
            $out .= '<input type="hidden" name="action" value="classin">';
4037
            $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4038
            $out .= $formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1);
4039
            $out .= '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4040
            $out .= '</form>';
4041
        } else {
4042
            if ($selected) {
4043
                $projet = new Project($this->db);
4044
                $projet->fetch($selected);
4045
                //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
4046
                $out .= $projet->getNomUrl(0, '', 1);
4047
            } else {
4048
                $out .= "&nbsp;";
4049
            }
4050
        }
4051
4052
        if (empty($nooutput)) {
4053
            print $out;
4054
            return '';
4055
        }
4056
        return $out;
4057
    }
4058
4059
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4060
    /**
4061
     * 	Show a form to select payment conditions
4062
     *
4063
     *  @param	int		$page        	Page
4064
     *  @param  string	$selected    	Id condition pre-selectionne
4065
     *  @param  string	$htmlname    	Name of select html field
4066
     * 	@param	int		$addempty		Add empty entry
4067
     *  @return	void
4068
     */
4069
    function form_conditions_reglement($page, $selected = '', $htmlname = 'cond_reglement_id', $addempty = 0)
4070
    {
4071
        // phpcs:enable
4072
        global $langs;
4073
        if ($htmlname != "none") {
4074
            print '<form method="post" action="' . $page . '">';
4075
            print '<input type="hidden" name="action" value="setconditions">';
4076
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4077
            $this->select_conditions_paiements($selected, $htmlname, -1, $addempty);
4078
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4079
            print '</form>';
4080
        } else {
4081
            if ($selected) {
4082
                $this->load_cache_conditions_paiements();
4083
                print $this->cache_conditions_paiements[$selected]['label'];
4084
            } else {
4085
                print "&nbsp;";
4086
            }
4087
        }
4088
    }
4089
4090
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4091
    /**
4092
     *  Show a form to select a delivery delay
4093
     *
4094
     *  @param  int		$page        	Page
4095
     *  @param  string	$selected    	Id condition pre-selectionne
4096
     *  @param  string	$htmlname    	Name of select html field
4097
     * 	@param	int		$addempty		Ajoute entree vide
4098
     *  @return	void
4099
     */
4100
    function form_availability($page, $selected = '', $htmlname = 'availability', $addempty = 0)
4101
    {
4102
        // phpcs:enable
4103
        global $langs;
4104
        if ($htmlname != "none") {
4105
            print '<form method="post" action="' . $page . '">';
4106
            print '<input type="hidden" name="action" value="setavailability">';
4107
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4108
            $this->selectAvailabilityDelay($selected, $htmlname, -1, $addempty);
4109
            print '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4110
            print '</form>';
4111
        } else {
4112
            if ($selected) {
4113
                $this->load_cache_availability();
4114
                print $this->cache_availability[$selected]['label'];
4115
            } else {
4116
                print "&nbsp;";
4117
            }
4118
        }
4119
    }
4120
4121
    /**
4122
     * 	Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
4123
     *  List found into table c_input_reason loaded by loadCacheInputReason
4124
     *
4125
     *  @param  string	$page        	Page
4126
     *  @param  string	$selected    	Id condition pre-selectionne
4127
     *  @param  string	$htmlname    	Name of select html field
4128
     * 	@param	int		$addempty		Add empty entry
4129
     *  @return	void
4130
     */
4131
    function formInputReason($page, $selected = '', $htmlname = 'demandreason', $addempty = 0)
4132
    {
4133
        global $langs;
4134
        if ($htmlname != "none") {
4135
            print '<form method="post" action="' . $page . '">';
4136
            print '<input type="hidden" name="action" value="setdemandreason">';
4137
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4138
            $this->selectInputReason($selected, $htmlname, -1, $addempty);
4139
            print '<input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
4140
            print '</form>';
4141
        } else {
4142
            if ($selected) {
4143
                $this->loadCacheInputReason();
4144
                foreach ($this->cache_demand_reason as $key => $val) {
4145
                    if ($val['id'] == $selected) {
4146
                        print $val['label'];
4147
                        break;
4148
                    }
4149
                }
4150
            } else {
4151
                print "&nbsp;";
4152
            }
4153
        }
4154
    }
4155
4156
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4157
    /**
4158
     *    Show a form + html select a date
4159
     *
4160
     *    @param	string		$page        	Page
4161
     *    @param	string		$selected    	Date preselected
4162
     *    @param    string		$htmlname    	Html name of date input fields or 'none'
4163
     *    @param    int			$displayhour 	Display hour selector
4164
     *    @param    int			$displaymin		Display minutes selector
4165
     *    @param	int			$nooutput		1=No print output, return string
4166
     *    @return	string
4167
     *    @see		selectDate
4168
     */
4169
    function form_date($page, $selected, $htmlname, $displayhour = 0, $displaymin = 0, $nooutput = 0)
4170
    {
4171
        // phpcs:enable
4172
        global $langs;
4173
4174
        $ret = '';
4175
4176
        if ($htmlname != "none") {
4177
            $ret .= '<form method="post" action="' . $page . '" name="form' . $htmlname . '">';
4178
            $ret .= '<input type="hidden" name="action" value="set' . $htmlname . '">';
4179
            $ret .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4180
            $ret .= '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4181
            $ret .= '<tr><td>';
4182
            $ret .= $this->selectDate($selected, $htmlname, $displayhour, $displaymin, 1, 'form' . $htmlname, 1, 0);
4183
            $ret .= '</td>';
4184
            $ret .= '<td align="left"><input type="submit" class="button" value="' . $langs->trans("Modify") . '"></td>';
4185
            $ret .= '</tr></table></form>';
4186
        } else {
4187
            if ($displayhour)
4188
                $ret .= DolUtils::dol_print_date($selected, 'dayhour');
4189
            else
4190
                $ret .= DolUtils::dol_print_date($selected, 'day');
4191
        }
4192
4193
        if (empty($nooutput))
4194
            print $ret;
4195
        return $ret;
4196
    }
4197
4198
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4199
    /**
4200
     *  Show a select form to choose a user
4201
     *
4202
     *  @param	string	$page        	Page
4203
     *  @param  string	$selected    	Id of user preselected
4204
     *  @param  string	$htmlname    	Name of input html field. If 'none', we just output the user link.
4205
     *  @param  array	$exclude		List of users id to exclude
4206
     *  @param  array	$include        List of users id to include
4207
     *  @return	void
4208
     */
4209
    function form_users($page, $selected = '', $htmlname = 'userid', $exclude = '', $include = '')
4210
    {
4211
        // phpcs:enable
4212
        global $langs;
4213
4214
        if ($htmlname != "none") {
4215
            print '<form method="POST" action="' . $page . '" name="form' . $htmlname . '">';
4216
            print '<input type="hidden" name="action" value="set' . $htmlname . '">';
4217
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4218
            print $this->select_dolusers($selected, $htmlname, 1, $exclude, 0, $include);
4219
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4220
            print '</form>';
4221
        } else {
4222
            if ($selected) {
4223
                require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
4224
                $theuser = new User($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4225
                $theuser->fetch($selected);
4226
                print $theuser->getNomUrl(1);
4227
            } else {
4228
                print "&nbsp;";
4229
            }
4230
        }
4231
    }
4232
4233
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4234
    /**
4235
     *    Show form with payment mode
4236
     *
4237
     *    @param	string	$page        	Page
4238
     *    @param    int		$selected    	Id mode pre-selectionne
4239
     *    @param    string	$htmlname    	Name of select html field
4240
     *    @param  	string	$filtertype		To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz))
4241
     *    @param    int     $active         Active or not, -1 = all
4242
     *    @return	void
4243
     */
4244
    function form_modes_reglement($page, $selected = '', $htmlname = 'mode_reglement_id', $filtertype = '', $active = 1)
4245
    {
4246
        // phpcs:enable
4247
        global $langs;
4248
        if ($htmlname != "none") {
4249
            print '<form method="POST" action="' . $page . '">';
4250
            print '<input type="hidden" name="action" value="setmode">';
4251
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4252
            $this->select_types_paiements($selected, $htmlname, $filtertype, 0, 0, 0, 0, $active);
4253
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4254
            print '</form>';
4255
        } else {
4256
            if ($selected) {
4257
                $this->load_cache_types_paiements();
4258
                print $this->cache_types_paiements[$selected]['label'];
4259
            } else {
4260
                print "&nbsp;";
4261
            }
4262
        }
4263
    }
4264
4265
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4266
    /**
4267
     *    Show form with multicurrency code
4268
     *
4269
     *    @param	string	$page        	Page
4270
     *    @param    string	$selected    	code pre-selectionne
4271
     *    @param    string	$htmlname    	Name of select html field
4272
     *    @return	void
4273
     */
4274
    function form_multicurrency_code($page, $selected = '', $htmlname = 'multicurrency_code')
4275
    {
4276
        // phpcs:enable
4277
        global $langs;
4278
        if ($htmlname != "none") {
4279
            print '<form method="POST" action="' . $page . '">';
4280
            print '<input type="hidden" name="action" value="setmulticurrencycode">';
4281
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4282
            print $this->selectMultiCurrency($selected, $htmlname, 0);
4283
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4284
            print '</form>';
4285
        } else {
4286
            dol_include_once('/core/lib/company.lib.php');
4287
            print !empty($selected) ? currency_name($selected, 1) : '&nbsp;';
4288
        }
4289
    }
4290
4291
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4292
    /**
4293
     *    Show form with multicurrency rate
4294
     *
4295
     *    @param	string	$page        	Page
4296
     *    @param    double	$rate	    	Current rate
4297
     *    @param    string	$htmlname    	Name of select html field
4298
     *    @param    string  $currency       Currency code to explain the rate
4299
     *    @return	void
4300
     */
4301
    function form_multicurrency_rate($page, $rate = '', $htmlname = 'multicurrency_tx', $currency = '')
4302
    {
4303
        // phpcs:enable
4304
        global $langs, $mysoc, $conf;
4305
4306
        if ($htmlname != "none") {
4307
            print '<form method="POST" action="' . $page . '">';
4308
            print '<input type="hidden" name="action" value="setmulticurrencyrate">';
4309
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4310
            print '<input type="text" name="' . $htmlname . '" value="' . (!empty($rate) ? price($rate) : 1) . '" size="10" /> ';
4311
            print '<select name="calculation_mode">';
4312
            print '<option value="1">' . $currency . ' > ' . Globals::$conf->currency . '</option>';
4313
            print '<option value="2">' . Globals::$conf->currency . ' > ' . $currency . '</option>';
4314
            print '</select> ';
4315
            print '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4316
            print '</form>';
4317
        } else {
4318
            if (!empty($rate)) {
4319
                print price($rate, 1, $langs, 1, 0);
4320
                if ($currency && $rate != 1)
4321
                    print ' &nbsp; (' . price($rate, 1, $langs, 1, 0) . ' ' . $currency . ' = 1 ' . Globals::$conf->currency . ')';
4322
            }
4323
            else {
4324
                print 1;
4325
            }
4326
        }
4327
    }
4328
4329
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4330
    /**
4331
     * 	Show a select box with available absolute discounts
4332
     *
4333
     *  @param  string	$page        	Page URL where form is shown
4334
     *  @param  int		$selected    	Value pre-selected
4335
     * 	@param  string	$htmlname    	Name of SELECT component. If 'none', not changeable. Example 'remise_id'.
4336
     * 	@param	int		$socid			Third party id
4337
     * 	@param	float	$amount			Total amount available
4338
     * 	@param	string	$filter			SQL filter on discounts
4339
     * 	@param	int		$maxvalue		Max value for lines that can be selected
4340
     *  @param  string	$more           More string to add
4341
     *  @param  int     $hidelist       1=Hide list
4342
     *  @param	int		$discount_type	0 => customer discount, 1 => supplier discount
4343
     *  @return	void
4344
     */
4345
    function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter = '', $maxvalue = 0, $more = '', $hidelist = 0, $discount_type = 0)
4346
    {
4347
        // phpcs:enable
4348
        global $conf, $langs;
4349
        if ($htmlname != "none") {
4350
            print '<form method="post" action="' . $page . '">';
4351
            print '<input type="hidden" name="action" value="setabsolutediscount">';
4352
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4353
            print '<div class="inline-block">';
4354
            if (!empty($discount_type)) {
4355
                if (!empty(Globals::$conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
4356
                    if (!$filter || $filter == "fk_invoice_supplier_source IS NULL")
4357
                        $translationKey = 'HasAbsoluteDiscountFromSupplier';    // If we want deposit to be substracted to payments only and not to total of final invoice
4358
                    else
4359
                        $translationKey = 'HasCreditNoteFromSupplier';
4360
                }
4361
                else {
4362
                    if (!$filter || $filter == "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')")
4363
                        $translationKey = 'HasAbsoluteDiscountFromSupplier';
4364
                    else
4365
                        $translationKey = 'HasCreditNoteFromSupplier';
4366
                }
4367
            } else {
4368
                if (!empty(Globals::$conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
4369
                    if (!$filter || $filter == "fk_facture_source IS NULL")
4370
                        $translationKey = 'CompanyHasAbsoluteDiscount';    // If we want deposit to be substracted to payments only and not to total of final invoice
4371
                    else
4372
                        $translationKey = 'CompanyHasCreditNote';
4373
                }
4374
                else {
4375
                    if (!$filter || $filter == "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')")
4376
                        $translationKey = 'CompanyHasAbsoluteDiscount';
4377
                    else
4378
                        $translationKey = 'CompanyHasCreditNote';
4379
                }
4380
            }
4381
            print $langs->trans($translationKey, price($amount, 0, $langs, 0, 0, -1, Globals::$conf->currency));
4382
            if (empty($hidelist))
4383
                print ': ';
4384
            print '</div>';
4385
            if (empty($hidelist)) {
4386
                print '<div class="inline-block" style="padding-right: 10px">';
4387
                $newfilter = 'discount_type=' . intval($discount_type);
4388
                if (!empty($discount_type)) {
4389
                    $newfilter .= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available
4390
                } else {
4391
                    $newfilter .= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available
4392
                }
4393
                if ($filter)
4394
                    $newfilter .= ' AND (' . $filter . ')';
4395
                $nbqualifiedlines = $this->select_remises($selected, $htmlname, $newfilter, $socid, $maxvalue);
4396
                if ($nbqualifiedlines > 0) {
4397
                    print ' &nbsp; <input type="submit" class="button" value="' . DolUtils::dol_escape_htmltag($langs->trans("UseLine")) . '"';
4398
                    if (!empty($discount_type) && $filter && $filter != "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')")
4399
                        print ' title="' . $langs->trans("UseCreditNoteInInvoicePayment") . '"';
4400
                    if (empty($discount_type) && $filter && $filter != "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')")
4401
                        print ' title="' . $langs->trans("UseCreditNoteInInvoicePayment") . '"';
4402
4403
                    print '>';
4404
                }
4405
                print '</div>';
4406
            }
4407
            if ($more) {
4408
                print '<div class="inline-block">';
4409
                print $more;
4410
                print '</div>';
4411
            }
4412
            print '</form>';
4413
        } else {
4414
            if ($selected) {
4415
                print $selected;
4416
            } else {
4417
                print "0";
4418
            }
4419
        }
4420
    }
4421
4422
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4423
    /**
4424
     *    Show forms to select a contact
4425
     *
4426
     *    @param	string		$page        	Page
4427
     *    @param	Societe		$societe		Filter on third party
4428
     *    @param    int			$selected    	Id contact pre-selectionne
4429
     *    @param    string		$htmlname    	Name of HTML select. If 'none', we just show contact link.
4430
     *    @return	void
4431
     */
4432
    function form_contacts($page, $societe, $selected = '', $htmlname = 'contactid')
4433
    {
4434
        // phpcs:enable
4435
        global $langs, $conf;
4436
4437
        if ($htmlname != "none") {
4438
            print '<form method="post" action="' . $page . '">';
4439
            print '<input type="hidden" name="action" value="set_contact">';
4440
            print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4441
            print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4442
            print '<tr><td>';
4443
            $num = $this->select_contacts($societe->id, $selected, $htmlname);
4444
            if ($num == 0) {
4445
                $addcontact = (!empty(Globals::$conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
4446
                print '<a href="' . DOL_URL_ROOT . '/contact/card.php?socid=' . $societe->id . '&amp;action=create&amp;backtoreferer=1">' . $addcontact . '</a>';
4447
            }
4448
            print '</td>';
4449
            print '<td align="left"><input type="submit" class="button" value="' . $langs->trans("Modify") . '"></td>';
4450
            print '</tr></table></form>';
4451
        } else {
4452
            if ($selected) {
4453
                require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
4454
                $contact = new Contact($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4455
                $contact->fetch($selected);
4456
                print $contact->getFullName($langs);
4457
            } else {
4458
                print "&nbsp;";
4459
            }
4460
        }
4461
    }
4462
4463
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4464
    /**
4465
     *  Output html select to select thirdparty
4466
     *
4467
     *  @param	string	$page       	Page
4468
     *  @param  string	$selected   	Id preselected
4469
     *  @param  string	$htmlname		Name of HTML select
4470
     *  @param  string	$filter         optional filters criteras
4471
     * 	@param	int		$showempty		Add an empty field
4472
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
4473
     * 	@param	int		$forcecombo		Force to use combo box
4474
     *  @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')))
4475
     *  @param  int     $nooutput       No print output. Return it only.
4476
     *  @return	void
4477
     */
4478
    function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0)
4479
    {
4480
        // phpcs:enable
4481
        global $langs;
4482
4483
        $out = '';
4484
        if ($htmlname != "none") {
4485
            $out .= '<form method="post" action="' . $page . '">';
4486
            $out .= '<input type="hidden" name="action" value="set_thirdparty">';
4487
            $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
4488
            $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
4489
            $out .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
4490
            $out .= '</form>';
4491
        } else {
4492
            if ($selected) {
4493
                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
4494
                $soc = new Societe($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4495
                $soc->fetch($selected);
4496
                $out .= $soc->getNomUrl($langs);
4497
            } else {
4498
                $out .= "&nbsp;";
4499
            }
4500
        }
4501
4502
        if ($nooutput)
4503
            return $out;
4504
        else
4505
            print $out;
4506
    }
4507
4508
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4509
    /**
4510
     *    Retourne la liste des devises, dans la langue de l'utilisateur
4511
     *
4512
     *    @param	string	$selected    preselected currency code
4513
     *    @param    string	$htmlname    name of HTML select list
4514
     *    @deprecated
4515
     *    @return	void
4516
     */
4517
    function select_currency($selected = '', $htmlname = 'currency_id')
4518
    {
4519
        // phpcs:enable
4520
        print $this->selectCurrency($selected, $htmlname);
4521
    }
4522
4523
    /**
4524
     *  Retourne la liste des devises, dans la langue de l'utilisateur
4525
     *
4526
     *  @param	string	$selected    preselected currency code
4527
     *  @param  string	$htmlname    name of HTML select list
4528
     * 	@return	string
4529
     */
4530
    function selectCurrency($selected = '', $htmlname = 'currency_id')
4531
    {
4532
        global $conf, $langs, $user;
4533
4534
        $langs->loadCacheCurrencies('');
4535
4536
        $out = '';
4537
4538
        if ($selected == 'euro' || $selected == 'euros')
4539
            $selected = 'EUR';   // Pour compatibilite
4540
4541
        $out .= '<select class="flat maxwidth200onsmartphone minwidth300" name="' . $htmlname . '" id="' . $htmlname . '">';
4542
        foreach ($langs->cache_currencies as $code_iso => $currency) {
4543
            if ($selected && $selected == $code_iso) {
4544
                $out .= '<option value="' . $code_iso . '" selected>';
4545
            } else {
4546
                $out .= '<option value="' . $code_iso . '">';
4547
            }
4548
            $out .= $currency['label'];
4549
            $out .= ' (' . $langs->getCurrencySymbol($code_iso) . ')';
4550
            $out .= '</option>';
4551
        }
4552
        $out .= '</select>';
4553
        if ($user->admin)
4554
            $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
4555
4556
        // Make select dynamic
4557
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4558
        $out .= ajax_combobox($htmlname);
4559
4560
        return $out;
4561
    }
4562
4563
    /**
4564
     * 	Return array of currencies in user language
4565
     *
4566
     *  @param	string	$selected    preselected currency code
4567
     *  @param  string	$htmlname    name of HTML select list
4568
     *  @param  integer	$useempty    1=Add empty line
4569
     * 	@return	string
4570
     */
4571
    function selectMultiCurrency($selected = '', $htmlname = 'multicurrency_code', $useempty = 0)
4572
    {
4573
        global $db, $conf, $langs, $user;
4574
4575
        $langs->loadCacheCurrencies('');        // Load ->cache_currencies
4576
4577
        $TCurrency = array();
4578
4579
        $sql = 'SELECT code FROM ' . MAIN_DB_PREFIX . 'multicurrency';
4580
        $sql .= " WHERE entity IN ('" . getEntity('mutlicurrency') . "')";
4581
        $resql = $db->query($sql);
4582
        if ($resql) {
4583
            while ($obj = $db->fetch_object($resql))
4584
                $TCurrency[$obj->code] = $obj->code;
4585
        }
4586
4587
        $out = '';
4588
        $out .= '<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
4589
        if ($useempty)
4590
            $out .= '<option value=""></option>';
4591
        // If company current currency not in table, we add it into list. Should always be available.
4592
        if (!in_array(Globals::$conf->currency, $TCurrency)) {
4593
            $TCurrency[Globals::$conf->currency] = Globals::$conf->currency;
4594
        }
4595
        if (count($TCurrency) > 0) {
4596
            foreach ($langs->cache_currencies as $code_iso => $currency) {
4597
                if (isset($TCurrency[$code_iso])) {
4598
                    if (!empty($selected) && $selected == $code_iso)
4599
                        $out .= '<option value="' . $code_iso . '" selected="selected">';
4600
                    else
4601
                        $out .= '<option value="' . $code_iso . '">';
4602
4603
                    $out .= $currency['label'];
4604
                    $out .= ' (' . $langs->getCurrencySymbol($code_iso) . ')';
4605
                    $out .= '</option>';
4606
                }
4607
            }
4608
        }
4609
4610
        $out .= '</select>';
4611
        // Make select dynamic
4612
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4613
        $out .= ajax_combobox($htmlname);
4614
4615
        return $out;
4616
    }
4617
4618
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4619
    /**
4620
     * 	Load into the cache vat rates of a country
4621
     *
4622
     * 	@param	string	$country_code		Country code with quotes ("'CA'", or "'CA,IN,...'")
4623
     * 	@return	int							Nb of loaded lines, 0 if already loaded, <0 if KO
4624
     */
4625
    function load_cache_vatrates($country_code)
4626
    {
4627
        // phpcs:enable
4628
        global $langs;
4629
4630
        $num = count($this->cache_vatrates);
4631
        if ($num > 0)
4632
            return $num;    // Cache already loaded
4633
4634
        dol_syslog(__METHOD__, LOG_DEBUG);
4635
4636
        $sql = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly";
4637
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
4638
        $sql .= " WHERE t.fk_pays = c.rowid";
4639
        $sql .= " AND t.active > 0";
4640
        $sql .= " AND c.code IN (" . $country_code . ")";
4641
        $sql .= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC";
4642
4643
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4644
        if ($resql) {
4645
            $num = $this->db->num_rows($resql);
4646
            if ($num) {
4647
                for ($i = 0; $i < $num; $i++) {
4648
                    $obj = $this->db->fetch_object($resql);
4649
                    $this->cache_vatrates[$i]['rowid'] = $obj->rowid;
4650
                    $this->cache_vatrates[$i]['code'] = $obj->code;
4651
                    $this->cache_vatrates[$i]['txtva'] = $obj->taux;
4652
                    $this->cache_vatrates[$i]['nprtva'] = $obj->recuperableonly;
4653
                    $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1;
4654
                    $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type;
4655
                    $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2;
4656
                    $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type;
4657
4658
                    $this->cache_vatrates[$i]['label'] = $obj->taux . '%' . ($obj->code ? ' (' . $obj->code . ')' : '');   // Label must contains only 0-9 , . % or *
4659
                    $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
4660
                    $positiverates = '';
4661
                    if ($obj->taux)
4662
                        $positiverates .= ($positiverates ? '/' : '') . $obj->taux;
4663
                    if ($obj->localtax1)
4664
                        $positiverates .= ($positiverates ? '/' : '') . $obj->localtax1;
4665
                    if ($obj->localtax2)
4666
                        $positiverates .= ($positiverates ? '/' : '') . $obj->localtax2;
4667
                    if (empty($positiverates))
4668
                        $positiverates = '0';
4669
                    $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates . ($obj->code ? ' (' . $obj->code . ')' : ''); // Must never be used as key, only label
4670
                }
4671
4672
                return $num;
4673
            }
4674
            else {
4675
                $this->error = '<font class="error">' . $langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code) . '</font>';
4676
                return -1;
4677
            }
4678
        } else {
4679
            $this->error = '<font class="error">' . $this->db->error() . '</font>';
4680
            return -2;
4681
        }
4682
    }
4683
4684
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4685
    /**
4686
     *  Output an HTML select vat rate.
4687
     *  The name of this function should be selectVat. We keep bad name for compatibility purpose.
4688
     *
4689
     *  @param	string	      $htmlname           Name of HTML select field
4690
     *  @param  float|string  $selectedrate       Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing.
4691
     *  @param  Societe	      $societe_vendeuse   Thirdparty seller
4692
     *  @param  Societe	      $societe_acheteuse  Thirdparty buyer
4693
     *  @param  int		      $idprod             Id product. O if unknown of NA.
4694
     *  @param  int		      $info_bits          Miscellaneous information on line (1 for NPR)
4695
     *  @param  int|string    $type               ''=Unknown, 0=Product, 1=Service (Used if idprod not defined)
4696
     *                  		                  Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle.
4697
     *                  					      Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle.
4698
     *                  					      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.
4699
     *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle.
4700
     *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle.
4701
     *                  					      Sinon la TVA proposee par defaut=0. Fin de regle.
4702
     *  @param	bool	     $options_only		  Return HTML options lines only (for ajax treatment)
4703
     *  @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
4704
     *  @return	string
4705
     */
4706
    function load_tva($htmlname = 'tauxtva', $selectedrate = '', $societe_vendeuse = '', $societe_acheteuse = '', $idprod = 0, $info_bits = 0, $type = '', $options_only = false, $mode = 0)
4707
    {
4708
        // phpcs:enable
4709
        global $langs, $conf, $mysoc;
4710
4711
        $langs->load('errors');
4712
4713
        $return = '';
4714
4715
        // Define defaultnpr, defaultttx and defaultcode
4716
        $defaultnpr = ($info_bits & 0x01);
4717
        $defaultnpr = (preg_match('/\*/', $selectedrate) ? 1 : $defaultnpr);
4718
        $defaulttx = str_replace('*', '', $selectedrate);
4719
        $defaultcode = '';
4720
        if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
4721
            $defaultcode = $reg[1];
4722
            $defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
4723
        }
4724
        //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode);
4725
        // Check parameters
4726
        if (is_object($societe_vendeuse) && !$societe_vendeuse->country_code) {
4727
            if ($societe_vendeuse->id == $mysoc->id) {
4728
                $return .= '<font class="error">' . $langs->trans("ErrorYourCountryIsNotDefined") . '</div>';
4729
            } else {
4730
                $return .= '<font class="error">' . $langs->trans("ErrorSupplierCountryIsNotDefined") . '</div>';
4731
            }
4732
            return $return;
4733
        }
4734
4735
        //var_dump($societe_acheteuse);
4736
        //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";
4737
        //exit;
4738
        // Define list of countries to use to search VAT rates to show
4739
        // First we defined code_country to use to find list
4740
        if (is_object($societe_vendeuse)) {
4741
            $code_country = "'" . $societe_vendeuse->country_code . "'";
4742
        } else {
4743
            $code_country = "'" . $mysoc->country_code . "'";   // Pour compatibilite ascendente
4744
        }
4745
        if (!empty(Globals::$conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) {    // If option to have vat for end customer for services is on
4746
            require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
4747
            if (!isInEEC($societe_vendeuse) && (!is_object($societe_acheteuse) || (isInEEC($societe_acheteuse) && !$societe_acheteuse->isACompany()))) {
4748
                // We also add the buyer
4749
                if (is_numeric($type)) {
4750
                    if ($type == 1) { // We know product is a service
4751
                        $code_country .= ",'" . $societe_acheteuse->country_code . "'";
4752
                    }
4753
                } else if (!$idprod) {  // We don't know type of product
4754
                    $code_country .= ",'" . $societe_acheteuse->country_code . "'";
4755
                } else {
4756
                    $prodstatic = new Product($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
4757
                    $prodstatic->fetch($idprod);
4758
                    if ($prodstatic->type == Product::TYPE_SERVICE) {   // We know product is a service
4759
                        $code_country .= ",'" . $societe_acheteuse->country_code . "'";
4760
                    }
4761
                }
4762
            }
4763
        }
4764
4765
        // Now we get list
4766
        $num = $this->load_cache_vatrates($code_country);   // If no vat defined, return -1 with message into this->error
4767
4768
        if ($num > 0) {
4769
            // Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '')
4770
            if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
4771
                $tmpthirdparty = new Societe($this->db);
4772
                $defaulttx = get_default_tva($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
4773
                $defaultnpr = get_default_npr($societe_vendeuse, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
4774
                if (preg_match('/\((.*)\)/', $defaulttx, $reg)) {
4775
                    $defaultcode = $reg[1];
4776
                    $defaulttx = preg_replace('/\s*\(.*\)/', '', $defaulttx);
4777
                }
4778
                if (empty($defaulttx)) {
4779
                    $defaultnpr = 0;
4780
                }
4781
            }
4782
4783
            // Si taux par defaut n'a pu etre determine, on prend dernier de la liste.
4784
            // Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant
4785
            if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
4786
                if (empty(Globals::$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) {
4787
                    $defaulttx = $this->cache_vatrates[$num - 1]['txtva'];
4788
                } else {
4789
                    $defaulttx = (Globals::$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : Globals::$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS);
4790
                }
4791
            }
4792
4793
            // Disabled if seller is not subject to VAT
4794
            $disabled = false;
4795
            $title = '';
4796
            if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0") {
4797
                // Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses
4798
                if (empty(Globals::$conf->global->OVERRIDE_VAT_FOR_EXPENSE_REPORT)) {
4799
                    $title = ' title="' . $langs->trans('VATIsNotUsed') . '"';
4800
                    $disabled = true;
4801
                }
4802
            }
4803
4804
            if (!$options_only) {
4805
                $return .= '<select class="flat minwidth75imp" id="' . $htmlname . '" name="' . $htmlname . '"' . ($disabled ? ' disabled' : '') . $title . '>';
4806
            }
4807
4808
            $selectedfound = false;
4809
            foreach ($this->cache_vatrates as $rate) {
4810
                // Keep only 0 if seller is not subject to VAT
4811
                if ($disabled && $rate['txtva'] != 0)
4812
                    continue;
4813
4814
                // Define key to use into select list
4815
                $key = $rate['txtva'];
4816
                $key .= $rate['nprtva'] ? '*' : '';
4817
                if ($mode > 0 && $rate['code'])
4818
                    $key .= ' (' . $rate['code'] . ')';
4819
                if ($mode < 0)
4820
                    $key = $rate['rowid'];
4821
4822
                $return .= '<option value="' . $key . '"';
4823
                if (!$selectedfound) {
4824
                    if ($defaultcode) { // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag
4825
                        if ($defaultcode == $rate['code']) {
4826
                            $return .= ' selected';
4827
                            $selectedfound = true;
4828
                        }
4829
                    } elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr) {
4830
                        $return .= ' selected';
4831
                        $selectedfound = true;
4832
                    }
4833
                }
4834
                $return .= '>';
4835
                //if (! empty(Globals::$conf->global->MAIN_VAT_SHOW_POSITIVE_RATES))
4836
                if ($mysoc->country_code == 'IN' || !empty(Globals::$conf->global->MAIN_VAT_LABEL_IS_POSITIVE_RATES)) {
4837
                    $return .= $rate['labelpositiverates'];
4838
                } else {
4839
                    $return .= vatrate($rate['label']);
4840
                }
4841
                //$return.=($rate['code']?' '.$rate['code']:'');
4842
                $return .= (empty($rate['code']) && $rate['nprtva']) ? ' *' : '';         // We show the *  (old behaviour only if new vat code is not used)
4843
4844
                $return .= '</option>';
4845
            }
4846
4847
            if (!$options_only)
4848
                $return .= '</select>';
4849
        }
4850
        else {
4851
            $return .= $this->error;
4852
        }
4853
4854
        $this->num = $num;
4855
        return $return;
4856
    }
4857
4858
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
4859
    /**
4860
     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4861
     *  Fields are preselected with :
4862
     *            	- set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4863
     *            	- local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4864
     *            	- Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4865
     *
4866
     * 	@param	timestamp	$set_time 		Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
4867
     * 	@param	string		$prefix			Prefix for fields name
4868
     * 	@param	int			$h				1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
4869
     * 	@param	int			$m				1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
4870
     * 	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4871
     * 	@param	string		$form_name 		Not used
4872
     * 	@param	int			$d				1=Show days, month, years
4873
     * 	@param	int			$addnowlink		Add a link "Now"
4874
     * 	@param	int			$nooutput		Do not output html string but return it
4875
     * 	@param 	int			$disabled		Disable input fields
4876
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4877
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another select_date field.
4878
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
4879
     *  @return	string|void					Nothing or string if nooutput is 1
4880
     *  @deprecated
4881
     *  @see    form_date, select_month, select_year, select_dayofweek
4882
     */
4883
    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 = '')
4884
    {
4885
        // phpcs:enable
4886
        $retstring = $this->selectDate($set_time, $prefix, $h, $m, $empty, $form_name, $d, $addnowlink, $disabled, $fullday, $addplusone, $adddateof);
4887
        if (!empty($nooutput)) {
4888
            return $retstring;
4889
        }
4890
        print $retstring;
4891
        return;
4892
    }
4893
4894
    /**
4895
     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4896
     *  Fields are preselected with :
4897
     *              - set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4898
     *              - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4899
     *              - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4900
     *
4901
     *  @param  timestamp   $set_time       Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
4902
     *  @param	string		$prefix			Prefix for fields name
4903
     *  @param	int			$h				1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
4904
     * 	@param	int			$m				1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
4905
     * 	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4906
     * 	@param	string		$form_name 		Not used
4907
     * 	@param	int			$d				1=Show days, month, years
4908
     * 	@param	int			$addnowlink		Add a link "Now"
4909
     * 	@param 	int			$disabled		Disable input fields
4910
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4911
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another selectDate field.
4912
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
4913
     * 	@return string                      Html for selectDate
4914
     *  @see    form_date, select_month, select_year, select_dayofweek
4915
     */
4916
    function selectDate($set_time = '', $prefix = 're', $h = 0, $m = 0, $empty = 0, $form_name = "", $d = 1, $addnowlink = 0, $disabled = 0, $fullday = '', $addplusone = '', $adddateof = '')
4917
    {
4918
        global $conf, $langs;
4919
4920
        $retstring = '';
4921
4922
        if ($prefix == '')
4923
            $prefix = 're';
4924
        if ($h == '')
4925
            $h = 0;
4926
        if ($m == '')
4927
            $m = 0;
4928
        $emptydate = 0;
4929
        $emptyhours = 0;
4930
        if ($empty == 1) {
4931
            $emptydate = 1;
4932
            $emptyhours = 1;
4933
        }
4934
        if ($empty == 2) {
4935
            $emptydate = 0;
4936
            $emptyhours = 1;
4937
        }
4938
        $orig_set_time = $set_time;
4939
4940
        if ($set_time === '' && $emptydate == 0) {
4941
            include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
4942
            $set_time = dol_now('tzuser') - (getServerTimeZoneInt('now') * 3600); // set_time must be relative to PHP server timezone
4943
        }
4944
4945
        // Analysis of the pre-selection date
4946
        if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/', $set_time, $reg)) { // deprecated usage
4947
            // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
4948
            $syear = (!empty($reg[1]) ? $reg[1] : '');
4949
            $smonth = (!empty($reg[2]) ? $reg[2] : '');
4950
            $sday = (!empty($reg[3]) ? $reg[3] : '');
4951
            $shour = (!empty($reg[4]) ? $reg[4] : '');
4952
            $smin = (!empty($reg[5]) ? $reg[5] : '');
4953
        } elseif (strval($set_time) != '' && $set_time != -1) {
4954
            // set_time est un timestamps (0 possible)
4955
            $syear = DolUtils::dol_print_date($set_time, "%Y");
4956
            $smonth = DolUtils::dol_print_date($set_time, "%m");
4957
            $sday = DolUtils::dol_print_date($set_time, "%d");
4958
            if ($orig_set_time != '') {
4959
                $shour = DolUtils::dol_print_date($set_time, "%H");
4960
                $smin = DolUtils::dol_print_date($set_time, "%M");
4961
                $ssec = DolUtils::dol_print_date($set_time, "%S");
4962
            } else {
4963
                $shour = '';
4964
                $smin = '';
4965
                $ssec = '';
4966
            }
4967
        } else {
4968
            // Date est '' ou vaut -1
4969
            $syear = '';
4970
            $smonth = '';
4971
            $sday = '';
4972
            $shour = !isset(Globals::$conf->global->MAIN_DEFAULT_DATE_HOUR) ? ($h == -1 ? '23' : '') : Globals::$conf->global->MAIN_DEFAULT_DATE_HOUR;
4973
            $smin = !isset(Globals::$conf->global->MAIN_DEFAULT_DATE_MIN) ? ($h == -1 ? '59' : '') : Globals::$conf->global->MAIN_DEFAULT_DATE_MIN;
4974
            $ssec = !isset(Globals::$conf->global->MAIN_DEFAULT_DATE_SEC) ? ($h == -1 ? '59' : '') : Globals::$conf->global->MAIN_DEFAULT_DATE_SEC;
4975
        }
4976
        if ($h == 3)
4977
            $shour = '';
4978
        if ($m == 3)
4979
            $smin = '';
4980
4981
        // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery'
4982
        $usecalendar = 'combo';
4983
        if (!empty(Globals::$conf->use_javascript_ajax) && (empty(Globals::$conf->global->MAIN_POPUP_CALENDAR) || Globals::$conf->global->MAIN_POPUP_CALENDAR != "none")) {
4984
            $usecalendar = ((empty(Globals::$conf->global->MAIN_POPUP_CALENDAR) || Globals::$conf->global->MAIN_POPUP_CALENDAR == 'eldy') ? 'jquery' : Globals::$conf->global->MAIN_POPUP_CALENDAR);
4985
        }
4986
4987
        if ($d) {
4988
            // Show date with popup
4989
            if ($usecalendar != 'combo') {
4990
                $formated_date = '';
4991
                //print "e".$set_time." t ".Globals::$conf->format_date_short;
4992
                if (strval($set_time) != '' && $set_time != -1) {
4993
                    //$formated_date=DolUtils::dol_print_date($set_time,Globals::$conf->format_date_short);
4994
                    $formated_date = DolUtils::dol_print_date($set_time, $langs->trans("FormatDateShortInput"));  // FormatDateShortInput for DolUtils::dol_print_date / FormatDateShortJavaInput that is same for javascript
4995
                }
4996
4997
                // Calendrier popup version eldy
4998
                if ($usecalendar == "eldy") {
4999
                    // Zone de saisie manuelle de la date
5000
                    $retstring .= '<input id="' . $prefix . '" name="' . $prefix . '" type="text" class="maxwidth75" maxlength="11" value="' . $formated_date . '"';
5001
                    $retstring .= ($disabled ? ' disabled' : '');
5002
                    $retstring .= ' onChange="dpChangeDay(\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\'); "';  // FormatDateShortInput for DolUtils::dol_print_date / FormatDateShortJavaInput that is same for javascript
5003
                    $retstring .= '>';
5004
5005
                    // Icone calendrier
5006
                    if (!$disabled) {
5007
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons"';
5008
                        $base = DOL_URL_ROOT . '/core/';
5009
                        $retstring .= ' onClick="showDP(\'' . $base . '\',\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\',\'' . $langs->defaultlang . '\');"';
5010
                        $retstring .= '>' . img_object($langs->trans("SelectDate"), 'calendarday', 'class="datecallink"') . '</button>';
5011
                    } else
5012
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons">' . img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"') . '</button>';
5013
5014
                    $retstring .= '<input type="hidden" id="' . $prefix . 'day"   name="' . $prefix . 'day"   value="' . $sday . '">' . "\n";
5015
                    $retstring .= '<input type="hidden" id="' . $prefix . 'month" name="' . $prefix . 'month" value="' . $smonth . '">' . "\n";
5016
                    $retstring .= '<input type="hidden" id="' . $prefix . 'year"  name="' . $prefix . 'year"  value="' . $syear . '">' . "\n";
5017
                }
5018
                elseif ($usecalendar == 'jquery') {
5019
                    if (!$disabled) {
5020
                        // Output javascript for datepicker
5021
                        $retstring .= "<script type='text/javascript'>";
5022
                        $retstring .= "$(function(){ $('#" . $prefix . "').datepicker({
5023
							dateFormat: '" . $langs->trans("FormatDateShortJQueryInput") . "',
5024
							autoclose: true,
5025
							todayHighlight: true,";
5026
                        if (!empty(Globals::$conf->dol_use_jmobile)) {
5027
                            $retstring .= "
5028
								beforeShow: function (input, datePicker) {
5029
									input.disabled = true;
5030
								},
5031
								onClose: function (dateText, datePicker) {
5032
									this.disabled = false;
5033
								},
5034
								";
5035
                        }
5036
                        // Note: We don't need monthNames, monthNamesShort, dayNames, dayNamesShort, dayNamesMin, they are set globally on datepicker component in lib_head.js.php
5037
                        if (empty(Globals::$conf->global->MAIN_POPUP_CALENDAR_ON_FOCUS)) {
5038
                            /*
5039
                              $retstring .= "
5040
                              showOn: 'button',
5041
                              buttonImage: '" . DOL_URL_ROOT . "/theme/" . Globals::$conf->theme . "/img/object_calendarday.png',
5042
                              buttonImageOnly: true";
5043
                             */
5044
                            $retstring .= "
5045
								showOn: 'button',
5046
								buttonImage: '" . DOL_BASE_URI . "/theme/" . Globals::$conf->theme . "/img/object_calendarday.png',
5047
								buttonImageOnly: true";
5048
                        }
5049
                        $retstring .= "
5050
							}) });";
5051
                        $retstring .= "</script>";
5052
                    }
5053
5054
                    // Zone de saisie manuelle de la date
5055
                    $retstring .= '<div class="nowrap inline-block">';
5056
                    $retstring .= '<input id="' . $prefix . '" name="' . $prefix . '" type="text" class="maxwidth75" maxlength="11" value="' . $formated_date . '"';
5057
                    $retstring .= ($disabled ? ' disabled' : '');
5058
                    $retstring .= ' onChange="dpChangeDay(\'' . $prefix . '\',\'' . $langs->trans("FormatDateShortJavaInput") . '\'); "';  // FormatDateShortInput for DolUtils::dol_print_date / FormatDateShortJavaInput that is same for javascript
5059
                    $retstring .= '>';
5060
5061
                    // Icone calendrier
5062
                    if (!$disabled) {
5063
                        /* Not required. Managed by option buttonImage of jquery
5064
                          $retstring.=img_object($langs->trans("SelectDate"),'calendarday','id="'.$prefix.'id" class="datecallink"');
5065
                          $retstring.="<script type='text/javascript'>";
5066
                          $retstring.="jQuery(document).ready(function() {";
5067
                          $retstring.='	jQuery("#'.$prefix.'id").click(function() {';
5068
                          $retstring.="    	jQuery('#".$prefix."').focus();";
5069
                          $retstring.='    });';
5070
                          $retstring.='});';
5071
                          $retstring.="</script>"; */
5072
                    } else {
5073
                        $retstring .= '<button id="' . $prefix . 'Button" type="button" class="dpInvisibleButtons">' . img_object($langs->trans("Disabled"), 'calendarday', 'class="datecallink"') . '</button>';
5074
                    }
5075
5076
                    $retstring .= '</div>';
5077
                    $retstring .= '<input type="hidden" id="' . $prefix . 'day"   name="' . $prefix . 'day"   value="' . $sday . '">' . "\n";
5078
                    $retstring .= '<input type="hidden" id="' . $prefix . 'month" name="' . $prefix . 'month" value="' . $smonth . '">' . "\n";
5079
                    $retstring .= '<input type="hidden" id="' . $prefix . 'year"  name="' . $prefix . 'year"  value="' . $syear . '">' . "\n";
5080
                } else {
5081
                    $retstring .= "Bad value of MAIN_POPUP_CALENDAR";
5082
                }
5083
            }
5084
            // Show date with combo selects
5085
            else {
5086
                //$retstring.='<div class="inline-block">';
5087
                // Day
5088
                $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50imp" id="' . $prefix . 'day" name="' . $prefix . 'day">';
5089
5090
                if ($emptydate || $set_time == -1) {
5091
                    $retstring .= '<option value="0" selected>&nbsp;</option>';
5092
                }
5093
5094
                for ($day = 1; $day <= 31; $day++) {
5095
                    $retstring .= '<option value="' . $day . '"' . ($day == $sday ? ' selected' : '') . '>' . $day . '</option>';
5096
                }
5097
5098
                $retstring .= "</select>";
5099
5100
                $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp" id="' . $prefix . 'month" name="' . $prefix . 'month">';
5101
                if ($emptydate || $set_time == -1) {
5102
                    $retstring .= '<option value="0" selected>&nbsp;</option>';
5103
                }
5104
5105
                // Month
5106
                for ($month = 1; $month <= 12; $month++) {
5107
                    $retstring .= '<option value="' . $month . '"' . ($month == $smonth ? ' selected' : '') . '>';
5108
                    $retstring .= DolUtils::dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
5109
                    $retstring .= "</option>";
5110
                }
5111
                $retstring .= "</select>";
5112
5113
                // Year
5114
                if ($emptydate || $set_time == -1) {
5115
                    $retstring .= '<input' . ($disabled ? ' disabled' : '') . ' placeholder="' . DolUtils::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 . '">';
5116
                } else {
5117
                    $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp" id="' . $prefix . 'year" name="' . $prefix . 'year">';
5118
5119
                    for ($year = $syear - 10; $year < $syear + 10; $year++) {
5120
                        $retstring .= '<option value="' . $year . '"' . ($year == $syear ? ' selected' : '') . '>' . $year . '</option>';
5121
                    }
5122
                    $retstring .= "</select>\n";
5123
                }
5124
                //$retstring.='</div>';
5125
            }
5126
        }
5127
5128
        if ($d && $h)
5129
            $retstring .= ($h == 2 ? '<br>' : ' ');
5130
5131
        if ($h) {
5132
            // Show hour
5133
            $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'hour' : '') . '" id="' . $prefix . 'hour" name="' . $prefix . 'hour">';
5134
            if ($emptyhours)
5135
                $retstring .= '<option value="-1">&nbsp;</option>';
5136
            for ($hour = 0; $hour < 24; $hour++) {
5137
                if (strlen($hour) < 2)
5138
                    $hour = "0" . $hour;
5139
                $retstring .= '<option value="' . $hour . '"' . (($hour == $shour) ? ' selected' : '') . '>' . $hour . (empty(Globals::$conf->dol_optimize_smallscreen) ? '' : 'H') . '</option>';
5140
            }
5141
            $retstring .= '</select>';
5142
            if ($m && empty(Globals::$conf->dol_optimize_smallscreen))
5143
                $retstring .= ":";
5144
        }
5145
5146
        if ($m) {
5147
            // Show minutes
5148
            $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'min' : '') . '" id="' . $prefix . 'min" name="' . $prefix . 'min">';
5149
            if ($emptyhours)
5150
                $retstring .= '<option value="-1">&nbsp;</option>';
5151
            for ($min = 0; $min < 60; $min++) {
5152
                if (strlen($min) < 2)
5153
                    $min = "0" . $min;
5154
                $retstring .= '<option value="' . $min . '"' . (($min == $smin) ? ' selected' : '') . '>' . $min . (empty(Globals::$conf->dol_optimize_smallscreen) ? '' : '') . '</option>';
5155
            }
5156
            $retstring .= '</select>';
5157
5158
            $retstring .= '<input type="hidden" name="' . $prefix . 'sec" value="' . $ssec . '">';
5159
        }
5160
5161
        // Add a "Now" link
5162
        if (Globals::$conf->use_javascript_ajax && $addnowlink) {
5163
            // Script which will be inserted in the onClick of the "Now" link
5164
            $reset_scripts = "";
5165
5166
            // Generate the date part, depending on the use or not of the javascript calendar
5167
            $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . DolUtils::dol_print_date(dol_now(), 'day') . '\');';
5168
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . DolUtils::dol_print_date(dol_now(), '%d') . '\');';
5169
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . DolUtils::dol_print_date(dol_now(), '%m') . '\');';
5170
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . DolUtils::dol_print_date(dol_now(), '%Y') . '\');';
5171
            /* if ($usecalendar == "eldy")
5172
              {
5173
              $base=DOL_URL_ROOT.'/core/';
5174
              $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');';
5175
              }
5176
              else
5177
              {
5178
              $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); ';
5179
              $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); ';
5180
              $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); ';
5181
              } */
5182
            // Update the hour part
5183
            if ($h) {
5184
                if ($fullday)
5185
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5186
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); ';
5187
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . DolUtils::dol_print_date(dol_now(), '%H') . '\');';
5188
                if ($fullday)
5189
                    $reset_scripts .= ' } ';
5190
            }
5191
            // Update the minute part
5192
            if ($m) {
5193
                if ($fullday)
5194
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5195
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); ';
5196
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . DolUtils::dol_print_date(dol_now(), '%M') . '\');';
5197
                if ($fullday)
5198
                    $reset_scripts .= ' } ';
5199
            }
5200
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
5201
            if ($reset_scripts && empty(Globals::$conf->dol_optimize_smallscreen)) {
5202
                $retstring .= ' <button class="dpInvisibleButtons datenowlink" id="' . $prefix . 'ButtonNow" type="button" name="_useless" value="now" onClick="' . $reset_scripts . '">';
5203
                $retstring .= $langs->trans("Now");
5204
                $retstring .= '</button> ';
5205
            }
5206
        }
5207
5208
        // Add a "Plus one hour" link
5209
        if (Globals::$conf->use_javascript_ajax && $addplusone) {
5210
            // Script which will be inserted in the onClick of the "Add plusone" link
5211
            $reset_scripts = "";
5212
5213
            // Generate the date part, depending on the use or not of the javascript calendar
5214
            $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . DolUtils::dol_print_date(dol_now(), 'day') . '\');';
5215
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . DolUtils::dol_print_date(dol_now(), '%d') . '\');';
5216
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . DolUtils::dol_print_date(dol_now(), '%m') . '\');';
5217
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . DolUtils::dol_print_date(dol_now(), '%Y') . '\');';
5218
            // Update the hour part
5219
            if ($h) {
5220
                if ($fullday)
5221
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5222
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . DolUtils::dol_print_date(dol_now(), '%H') . '\');';
5223
                if ($fullday)
5224
                    $reset_scripts .= ' } ';
5225
            }
5226
            // Update the minute part
5227
            if ($m) {
5228
                if ($fullday)
5229
                    $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
5230
                $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . DolUtils::dol_print_date(dol_now(), '%M') . '\');';
5231
                if ($fullday)
5232
                    $reset_scripts .= ' } ';
5233
            }
5234
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
5235
            if ($reset_scripts && empty(Globals::$conf->dol_optimize_smallscreen)) {
5236
                $retstring .= ' <button class="dpInvisibleButtons datenowlink" id="' . $prefix . 'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="' . $reset_scripts . '">';
5237
                $retstring .= $langs->trans("DateStartPlusOne");
5238
                $retstring .= '</button> ';
5239
            }
5240
        }
5241
5242
        // Add a "Plus one hour" link
5243
        if (Globals::$conf->use_javascript_ajax && $adddateof) {
5244
            $tmparray = dol_getdate($adddateof);
5245
            $retstring .= ' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\'' . DolUtils::dol_print_date($adddateof, 'day') . '\');jQuery(\'#reday\').val(\'' . $tmparray['mday'] . '\');jQuery(\'#remonth\').val(\'' . $tmparray['mon'] . '\');jQuery(\'#reyear\').val(\'' . $tmparray['year'] . '\');">' . $langs->trans("DateInvoice") . '</a>';
5246
        }
5247
5248
        return $retstring;
5249
    }
5250
5251
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
5252
    /**
5253
     * 	Function to show a form to select a duration on a page
5254
     *
5255
     * 	@param	string	$prefix   		Prefix for input fields
5256
     * 	@param  int	$iSecond  		    Default preselected duration (number of seconds or '')
5257
     * 	@param	int	$disabled           Disable the combo box
5258
     * 	@param	string	$typehour		If 'select' then input hour and input min is a combo,
5259
     * 						            if 'text' input hour is in text and input min is a text,
5260
     * 						            if 'textselect' input hour is in text and input min is a combo
5261
     *  @param	integer	$minunderhours	If 1, show minutes selection under the hours
5262
     * 	@param	int	$nooutput		    Do not output html string but return it
5263
     *  @return	string|void
5264
     */
5265
    function select_duration($prefix, $iSecond = '', $disabled = 0, $typehour = 'select', $minunderhours = 0, $nooutput = 0)
5266
    {
5267
        // phpcs:enable
5268
        global $langs;
5269
5270
        $retstring = '';
5271
5272
        $hourSelected = 0;
5273
        $minSelected = 0;
5274
5275
        // Hours
5276
        if ($iSecond != '') {
5277
            require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
5278
5279
            $hourSelected = convertSecondToTime($iSecond, 'allhour');
5280
            $minSelected = convertSecondToTime($iSecond, 'min');
5281
        }
5282
5283
        if ($typehour == 'select') {
5284
            $retstring .= '<select class="flat" id="select_' . $prefix . 'hour" name="' . $prefix . 'hour"' . ($disabled ? ' disabled' : '') . '>';
5285
            for ($hour = 0; $hour < 25; $hour++) { // For a duration, we allow 24 hours
5286
                $retstring .= '<option value="' . $hour . '"';
5287
                if ($hourSelected == $hour) {
5288
                    $retstring .= " selected";
5289
                }
5290
                $retstring .= ">" . $hour . "</option>";
5291
            }
5292
            $retstring .= "</select>";
5293
        } elseif ($typehour == 'text' || $typehour == 'textselect') {
5294
            $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) : '') . '">';
5295
        } else
5296
            return 'BadValueForParameterTypeHour';
5297
5298
        if ($typehour != 'text')
5299
            $retstring .= ' ' . $langs->trans('HourShort');
5300
        else
5301
            $retstring .= '<span class="hideonsmartphone">:</span>';
5302
5303
        // Minutes
5304
        if ($minunderhours)
5305
            $retstring .= '<br>';
5306
        else
5307
            $retstring .= '<span class="hideonsmartphone">&nbsp;</span>';
5308
5309
        if ($typehour == 'select' || $typehour == 'textselect') {
5310
            $retstring .= '<select class="flat" id="select_' . $prefix . 'min" name="' . $prefix . 'min"' . ($disabled ? ' disabled' : '') . '>';
5311
            for ($min = 0; $min <= 55; $min = $min + 5) {
5312
                $retstring .= '<option value="' . $min . '"';
5313
                if ($minSelected == $min)
5314
                    $retstring .= ' selected';
5315
                $retstring .= '>' . $min . '</option>';
5316
            }
5317
            $retstring .= "</select>";
5318
        }
5319
        elseif ($typehour == 'text') {
5320
            $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) : '') . '">';
5321
        }
5322
5323
        if ($typehour != 'text')
5324
            $retstring .= ' ' . $langs->trans('MinuteShort');
5325
5326
        //$retstring.="&nbsp;";
5327
5328
        if (!empty($nooutput))
5329
            return $retstring;
5330
5331
        print $retstring;
5332
        return;
5333
    }
5334
5335
    /**
5336
     * Generic method to select a component from a combo list.
5337
     * This is the generic method that will replace all specific existing methods.
5338
     *
5339
     * @param 	string			$objectdesc			Objectclassname:Objectclasspath
5340
     * @param	string			$htmlname			Name of HTML select component
5341
     * @param	int				$preselectedvalue	Preselected value (ID of element)
5342
     * @param	string			$showempty			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
5343
     * @param	string			$searchkey			Search criteria
5344
     * @param	string			$placeholder		Place holder
5345
     * @param	string			$morecss			More CSS
5346
     * @param	string			$moreparams			More params provided to ajax call
5347
     * @param	int				$forcecombo			Force to load all values and output a standard combobox (with no beautification)
5348
     * @return	string								Return HTML string
5349
     * @see selectForFormsList select_thirdparty
5350
     */
5351
    function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0)
5352
    {
5353
        global $conf, $user;
5354
5355
        $objecttmp = null;
5356
5357
        $InfoFieldList = explode(":", $objectdesc);
5358
        $classname = $InfoFieldList[0];
5359
        $classpath = $InfoFieldList[1];
5360
        if (!empty($classpath)) {
5361
            dol_include_once($classpath);
5362
            if ($classname && class_exists($classname)) {
5363
                $objecttmp = new $classname($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
5364
            }
5365
        }
5366
        if (!is_object($objecttmp)) {
5367
            dol_syslog('Error bad setup of type for field ' . $InfoFieldList, LOG_WARNING);
5368
            return 'Error bad setup of type for field ' . join(',', $InfoFieldList);
5369
        }
5370
5371
        $prefixforautocompletemode = $objecttmp->element;
5372
        if ($prefixforautocompletemode == 'societe')
5373
            $prefixforautocompletemode = 'company';
5374
        $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) . '_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
5375
5376
        dol_syslog(get_class($this) . "::selectForForms", LOG_DEBUG);
5377
5378
        $out = '';
5379
        if (!empty(Globals::$conf->use_javascript_ajax) && !empty(Globals::$conf->global->$confkeyforautocompletemode) && !$forcecombo) {
5380
            $objectdesc = $classname . ':' . $classpath;
5381
            $urlforajaxcall = DOL_URL_ROOT . '/core/ajax/selectobject.php';
5382
            //if ($objecttmp->element == 'societe') $urlforajaxcall = DOL_URL_ROOT.'/societe/ajax/company.php';
5383
            // No immediate load of all database
5384
            $urloption = 'htmlname=' . $htmlname . '&outjson=1&objectdesc=' . $objectdesc . ($moreparams ? $moreparams : '');
5385
            // Activate the auto complete using ajax call.
5386
            $out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, Globals::$conf->global->$confkeyforautocompletemode, 0, array());
5387
            $out .= '<style type="text/css">.ui-autocomplete { z-index: 250; }</style>';
5388
            if ($placeholder)
5389
                $placeholder = ' placeholder="' . $placeholder . '"';
5390
            $out .= '<input type="text" class="' . $morecss . '" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $preselectedvalue . '"' . $placeholder . ' />';
5391
        }
5392
        else {
5393
            // Immediate load of all database
5394
            $out .= $this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo);
5395
        }
5396
5397
        return $out;
5398
    }
5399
5400
    /**
5401
     * Output html form to select an object.
5402
     * Note, this function is called by selectForForms or by ajax selectobject.php
5403
     *
5404
     * @param 	Object			$objecttmp			Object
5405
     * @param	string			$htmlname			Name of HTML select component
5406
     * @param	int				$preselectedvalue	Preselected value (ID of element)
5407
     * @param	string			$showempty			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
5408
     * @param	string			$searchkey			Search value
5409
     * @param	string			$placeholder		Place holder
5410
     * @param	string			$morecss			More CSS
5411
     * @param	string			$moreparams			More params provided to ajax call
5412
     * @param	int				$forcecombo			Force to load all values and output a standard combobox (with no beautification)
5413
     * @param	int				$outputmode			0=HTML select string, 1=Array
5414
     * @return	string								Return HTML string
5415
     * @see selectForForms
5416
     */
5417
    function selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $outputmode = 0)
5418
    {
5419
        global $conf, $langs, $user;
5420
5421
        $prefixforautocompletemode = $objecttmp->element;
5422
        if ($prefixforautocompletemode == 'societe')
5423
            $prefixforautocompletemode = 'company';
5424
        $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) . '_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
5425
5426
        $fieldstoshow = 't.ref';
5427
        if (!empty($objecttmp->fields)) { // For object that declare it, it is better to use declared fields ( like societe, contact, ...)
5428
            $tmpfieldstoshow = '';
5429
            foreach ($objecttmp->fields as $key => $val) {
5430
                if ($val['showoncombobox'])
5431
                    $tmpfieldstoshow .= ($tmpfieldstoshow ? ',' : '') . 't.' . $key;
5432
            }
5433
            if ($tmpfieldstoshow)
5434
                $fieldstoshow = $tmpfieldstoshow;
5435
        }
5436
5437
        $out = '';
5438
        $outarray = array();
5439
5440
        $num = 0;
5441
5442
        // Search data
5443
        $sql = "SELECT t.rowid, " . $fieldstoshow . " FROM " . MAIN_DB_PREFIX . $objecttmp->table_element . " as t";
5444
        if ($objecttmp->ismultientitymanaged == 2)
5445
            if (!$user->rights->societe->client->voir && !$user->societe_id)
5446
                $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
5447
        $sql .= " WHERE 1=1";
5448
        if (!empty($objecttmp->ismultientitymanaged))
5449
            $sql .= " AND t.entity IN (" . getEntity($objecttmp->table_element) . ")";
5450
        if ($objecttmp->ismultientitymanaged == 1 && !empty($user->societe_id)) {
5451
            if ($objecttmp->element == 'societe')
5452
                $sql .= " AND t.rowid = " . $user->societe_id;
5453
            else
5454
                $sql .= " AND t.fk_soc = " . $user->societe_id;
5455
        }
5456
        if ($searchkey != '')
5457
            $sql .= natural_search(explode(',', $fieldstoshow), $searchkey);
5458
        if ($objecttmp->ismultientitymanaged == 2)
5459
            if (!$user->rights->societe->client->voir && !$user->societe_id)
5460
                $sql .= " AND t.rowid = sc.fk_soc AND sc.fk_user = " . $user->id;
5461
        $sql .= $this->db->order($fieldstoshow, "ASC");
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
5462
        //$sql.=$this->db->plimit($limit, 0);
5463
        // Build output string
5464
        $resql = $this->db->query($sql);
5465
        if ($resql) {
5466
            if (!$forcecombo) {
5467
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
5468
                $out .= ajax_combobox($htmlname, null, Globals::$conf->global->$confkeyforautocompletemode);
5469
            }
5470
5471
            // Construct $out and $outarray
5472
            $out .= '<select id="' . $htmlname . '" class="flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($moreparams ? ' ' . $moreparams : '') . ' name="' . $htmlname . '">' . "\n";
5473
5474
            // Warning: Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'. Seems it is no more true with selec2 v4
5475
            $textifempty = '&nbsp;';
5476
5477
            //if (! empty(Globals::$conf->use_javascript_ajax) || $forcecombo) $textifempty='';
5478
            if (!empty(Globals::$conf->global->$confkeyforautocompletemode)) {
5479
                if ($showempty && !is_numeric($showempty))
5480
                    $textifempty = $langs->trans($showempty);
5481
                else
5482
                    $textifempty .= $langs->trans("All");
5483
            }
5484
            if ($showempty)
5485
                $out .= '<option value="-1">' . $textifempty . '</option>' . "\n";
5486
5487
            $num = $this->db->num_rows($resql);
5488
            $i = 0;
5489
            if ($num) {
5490
                while ($i < $num) {
5491
                    $obj = $this->db->fetch_object($resql);
5492
                    $label = '';
5493
                    $tmparray = explode(',', $fieldstoshow);
5494
                    foreach ($tmparray as $key => $val) {
5495
                        $val = preg_replace('/t\./', '', $val);
5496
                        $label .= (($label && $obj->$val) ? ' - ' : '') . $obj->$val;
5497
                    }
5498
                    if (empty($outputmode)) {
5499
                        if ($preselectedvalue > 0 && $preselectedvalue == $obj->rowid) {
5500
                            $out .= '<option value="' . $obj->rowid . '" selected>' . $label . '</option>';
5501
                        } else {
5502
                            $out .= '<option value="' . $obj->rowid . '">' . $label . '</option>';
5503
                        }
5504
                    } else {
5505
                        array_push($outarray, array('key' => $obj->rowid, 'value' => $label, 'label' => $label));
5506
                    }
5507
5508
                    $i++;
5509
                    if (($i % 10) == 0)
5510
                        $out .= "\n";
5511
                }
5512
            }
5513
5514
            $out .= '</select>' . "\n";
5515
        }
5516
        else {
5517
            DolUtils::dol_print_error($this->db);
5518
        }
5519
5520
        $this->result = array('nbofelement' => $num);
5521
5522
        if ($outputmode)
5523
            return $outarray;
5524
        return $out;
5525
    }
5526
5527
    /**
5528
     * 	Return a HTML select string, built from an array of key+value.
5529
     *  Note: Do not apply langs->trans function on returned content, content may be entity encoded twice.
5530
     *
5531
     * 	@param	string			$htmlname			Name of html select area. Must start with "multi" if this is a multiselect
5532
     * 	@param	array			$array				Array (key => value)
5533
     * 	@param	string|string[]	$id					Preselected key or preselected keys for multiselect
5534
     * 	@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.
5535
     * 	@param	int				$key_in_label		1 to show key into label with format "[key] value"
5536
     * 	@param	int				$value_as_key		1 to use value as key
5537
     * 	@param  string			$moreparam			Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
5538
     * 	@param  int				$translate			1=Translate and encode value
5539
     * 	@param	int				$maxlen				Length maximum for labels
5540
     * 	@param	int				$disabled			Html select box is disabled
5541
     *  @param	string			$sort				'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order
5542
     *  @param	string			$morecss			Add more class to css styles
5543
     *  @param	int				$addjscombo			Add js combo
5544
     *  @param  string          $moreparamonempty	Add more param on the empty option line. Not used if show_empty not set
5545
     *  @param  int             $disablebademail	Check if an email is found into value and if not disable and colorize entry
5546
     *  @param  int             $nohtmlescape		No html escaping.
5547
     * 	@return	string								HTML select string.
5548
     *  @see multiselectarray
5549
     */
5550
    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)
5551
    {
5552
        global $conf, $langs;
5553
5554
        // Do we want a multiselect ?
5555
        //$jsbeautify = 0;
5556
        //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1;
5557
        $jsbeautify = 1;
5558
5559
        if ($value_as_key)
5560
            $array = array_combine($array, $array);
5561
5562
        $out = '';
5563
5564
        // Add code for jquery to use multiselect
5565
        if ($addjscombo && $jsbeautify) {
5566
            $minLengthToAutocomplete = 0;
5567
            $tmpplugin = empty(Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT) ? (constant('REQUIRE_JQUERY_MULTISELECT') ? constant('REQUIRE_JQUERY_MULTISELECT') : 'select2') : Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT;
5568
5569
            // Enhance with select2
5570
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
5571
            $out .= ajax_combobox($htmlname);
5572
        }
5573
5574
        $out .= '<select id="' . preg_replace('/^\./', '', $htmlname) . '" ' . ($disabled ? 'disabled ' : '') . 'class="flat ' . (preg_replace('/^\./', '', $htmlname)) . ($morecss ? ' ' . $morecss : '') . '"';
5575
        $out .= ' name="' . preg_replace('/^\./', '', $htmlname) . '" ' . ($moreparam ? $moreparam : '');
5576
        $out .= '>';
5577
5578
        if ($show_empty) {
5579
            $textforempty = ' ';
5580
            if (!empty(Globals::$conf->use_javascript_ajax))
5581
                $textforempty = '&nbsp;'; // If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
5582
            if (!is_numeric($show_empty))
5583
                $textforempty = $show_empty;
5584
            $out .= '<option class="optiongrey" ' . ($moreparamonempty ? $moreparamonempty . ' ' : '') . 'value="' . ($show_empty < 0 ? $show_empty : -1) . '"' . ($id == $show_empty ? ' selected' : '') . '>' . $textforempty . '</option>' . "\n";
5585
        }
5586
5587
        if (is_array($array)) {
5588
            // Translate
5589
            if ($translate) {
5590
                foreach ($array as $key => $value) {
5591
                    $array[$key] = $langs->trans($value);
5592
                }
5593
            }
5594
5595
            // Sort
5596
            if ($sort == 'ASC')
5597
                asort($array);
5598
            elseif ($sort == 'DESC')
5599
                arsort($array);
5600
5601
            foreach ($array as $key => $value) {
5602
                $disabled = '';
5603
                $style = '';
5604
                if (!empty($disablebademail)) {
5605
                    if (!preg_match('/&lt;.+@.+&gt;/', $value)) {
5606
                        //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value);
5607
                        $disabled = ' disabled';
5608
                        $style = ' class="warning"';
5609
                    }
5610
                }
5611
5612
                if ($key_in_label) {
5613
                    if (empty($nohtmlescape))
5614
                        $selectOptionValue = DolUtils::dol_escape_htmltag($key . ' - ' . ($maxlen ? dol_trunc($value, $maxlen) : $value));
5615
                    else
5616
                        $selectOptionValue = $key . ' - ' . ($maxlen ? dol_trunc($value, $maxlen) : $value);
5617
                }
5618
                else {
5619
                    if (empty($nohtmlescape))
5620
                        $selectOptionValue = DolUtils::dol_escape_htmltag($maxlen ? dol_trunc($value, $maxlen) : $value);
5621
                    else
5622
                        $selectOptionValue = $maxlen ? dol_trunc($value, $maxlen) : $value;
5623
                    if ($value == '' || $value == '-')
5624
                        $selectOptionValue = '&nbsp;';
5625
                }
5626
5627
                $out .= '<option value="' . $key . '"';
5628
                $out .= $style . $disabled;
5629
                if ($id != '' && $id == $key && !$disabled)
5630
                    $out .= ' selected';  // To preselect a value
5631
                if ($nohtmlescape)
5632
                    $out .= ' data-html="' . DolUtils::dol_escape_htmltag($selectOptionValue) . '"';
5633
                $out .= '>';
5634
                //var_dump($selectOptionValue);
5635
                $out .= $selectOptionValue;
5636
                $out .= "</option>\n";
5637
            }
5638
        }
5639
5640
        $out .= "</select>";
5641
        return $out;
5642
    }
5643
5644
    /**
5645
     * 	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.
5646
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5647
     *
5648
     * 	@param	string	$htmlname       		Name of html select area
5649
     * 	@param	string	$url					Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...)
5650
     * 	@param	string	$id             		Preselected key
5651
     * 	@param  string	$moreparam      		Add more parameters onto the select tag
5652
     * 	@param  string	$moreparamtourl 		Add more parameters onto the Ajax called URL
5653
     * 	@param	int		$disabled				Html select box is disabled
5654
     *  @param	int		$minimumInputLength		Minimum Input Length
5655
     *  @param	string	$morecss				Add more class to css styles
5656
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5657
     *  @param  string  $placeholder            String to use as placeholder
5658
     *  @param  integer $acceptdelayedhtml      1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
5659
     * 	@return	string   						HTML select string
5660
     *  @see selectArrayFilter, ajax_combobox in ajax.lib.php
5661
     */
5662
    static function selectArrayAjax($htmlname, $url, $id = '', $moreparam = '', $moreparamtourl = '', $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0)
5663
    {
5664
        global $conf, $langs;
5665
        global $delayedhtmlcontent;
5666
5667
        // TODO Use an internal dolibarr component instead of select2
5668
        if (empty(Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT'))
5669
            return '';
5670
5671
        $out = '<select type="text" class="' . $htmlname . ($morecss ? ' ' . $morecss : '') . '" ' . ($moreparam ? $moreparam . ' ' : '') . 'name="' . $htmlname . '"></select>';
5672
5673
        $tmpplugin = 'select2';
5674
        $outdelayed = "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
5675
	    	<script type="text/javascript">
5676
	    	$(document).ready(function () {
5677
5678
    	        ' . ($callurlonselect ? 'var saveRemoteData = [];' : '') . '
5679
5680
                $(".' . $htmlname . '").select2({
5681
			    	ajax: {
5682
				    	dir: "ltr",
5683
				    	url: "' . $url . '",
5684
				    	dataType: \'json\',
5685
				    	delay: 250,
5686
				    	data: function (params) {
5687
				    		return {
5688
						    	q: params.term, 	// search term
5689
				    			page: params.page
5690
				    		};
5691
			    		},
5692
			    		processResults: function (data) {
5693
			    			// parse the results into the format expected by Select2.
5694
			    			// since we are using custom formatting functions we do not need to alter the remote JSON data
5695
			    			//console.log(data);
5696
							saveRemoteData = data;
5697
				    	    /* format json result for select2 */
5698
				    	    result = []
5699
				    	    $.each( data, function( key, value ) {
5700
				    	       result.push({id: key, text: value.text});
5701
                            });
5702
			    			//return {results:[{id:\'none\', text:\'aa\'}, {id:\'rrr\', text:\'Red\'},{id:\'bbb\', text:\'Search a into projects\'}], more:false}
5703
			    			//console.log(result);
5704
			    			return {results: result, more: false}
5705
			    		},
5706
			    		cache: true
5707
			    	},
5708
	 				language: select2arrayoflanguage,
5709
					containerCssClass: \':all:\',					/* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
5710
				    placeholder: "' . dol_escape_js($placeholder) . '",
5711
			    	escapeMarkup: function (markup) { return markup; }, 	// let our custom formatter work
5712
			    	minimumInputLength: ' . $minimumInputLength . ',
5713
			        formatResult: function(result, container, query, escapeMarkup) {
5714
                        return escapeMarkup(result.text);
5715
                    },
5716
			    });
5717
5718
                ' . ($callurlonselect ? '
5719
                /* Code to execute a GET when we select a value */
5720
                $(".' . $htmlname . '").change(function() {
5721
			    	var selected = $(".' . $htmlname . '").val();
5722
                	console.log("We select in selectArrayAjax the entry "+selected)
5723
			        $(".' . $htmlname . '").val("");  /* reset visible combo value */
5724
    			    $.each( saveRemoteData, function( key, value ) {
5725
    				        if (key == selected)
5726
    			            {
5727
    			                 console.log("selectArrayAjax - Do a redirect to "+value.url)
5728
    			                 location.assign(value.url);
5729
    			            }
5730
                    });
5731
    			});' : '' ) . '
5732
5733
    	   });
5734
	       </script>';
5735
5736
        if ($acceptdelayedhtml) {
5737
            $delayedhtmlcontent .= $outdelayed;
5738
        } else {
5739
            $out .= $outdelayed;
5740
        }
5741
        return $out;
5742
    }
5743
5744
    /**
5745
     * 	Return a HTML select string, built from an array of key+value, but content returned into select is defined into $array parameter.
5746
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5747
     *
5748
     * 	@param	string	$htmlname       		Name of html select area
5749
     * 	@param	string	$array					Array (key=>array('text'=>'A text', 'url'=>'An url'), ...)
5750
     * 	@param	string	$id             		Preselected key
5751
     * 	@param  string	$moreparam      		Add more parameters onto the select tag
5752
     * 	@param	int		$disableFiltering		If set to 1, results are not filtered with searched string
5753
     * 	@param	int		$disabled				Html select box is disabled
5754
     *  @param	int		$minimumInputLength		Minimum Input Length
5755
     *  @param	string	$morecss				Add more class to css styles
5756
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5757
     *  @param  string  $placeholder            String to use as placeholder
5758
     *  @param  integer $acceptdelayedhtml      1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
5759
     * 	@return	string   						HTML select string
5760
     *  @see selectArrayAjax, ajax_combobox in ajax.lib.php
5761
     */
5762
    static function selectArrayFilter($htmlname, $array, $id = '', $moreparam = '', $disableFiltering = 0, $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0)
5763
    {
5764
        global $conf, $langs;
5765
        global $delayedhtmlcontent;
5766
5767
        // TODO Use an internal dolibarr component instead of select2
5768
        if (empty(Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT'))
5769
            return '';
5770
5771
        $out = '<select type="text" class="' . $htmlname . ($morecss ? ' ' . $morecss : '') . '" ' . ($moreparam ? $moreparam . ' ' : '') . 'name="' . $htmlname . '"><option></option></select>';
5772
5773
        $formattedarrayresult = array();
5774
5775
        foreach ($array as $key => $value) {
5776
            $o = new stdClass();
5777
            $o->id = $key;
5778
            $o->text = $value['text'];
5779
            $o->url = $value['url'];
5780
            $formattedarrayresult[] = $o;
5781
        }
5782
5783
        $tmpplugin = 'select2';
5784
        $outdelayed = "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
5785
			<script type="text/javascript">
5786
			$(document).ready(function () {
5787
				var data = ' . json_encode($formattedarrayresult) . ';
5788
5789
				' . ($callurlonselect ? 'var saveRemoteData = ' . json_encode($array) . ';' : '') . '
5790
5791
				$(".' . $htmlname . '").select2({
5792
					data: data,
5793
					language: select2arrayoflanguage,
5794
					containerCssClass: \':all:\',					/* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
5795
					placeholder: "' . dol_escape_js($placeholder) . '",
5796
					escapeMarkup: function (markup) { return markup; }, 	// let our custom formatter work
5797
					minimumInputLength: ' . $minimumInputLength . ',
5798
					formatResult: function(result, container, query, escapeMarkup) {
5799
						return escapeMarkup(result.text);
5800
					},
5801
					matcher: function (params, data) {
5802
5803
						if(! data.id) return null;';
5804
5805
        if ($callurlonselect) {
5806
            $outdelayed .= '
5807
5808
						var urlBase = data.url;
5809
						var separ = urlBase.indexOf("?") >= 0 ? "&" : "?";
5810
						/* console.log("params.term="+params.term); */
5811
						/* console.log("params.term encoded="+encodeURIComponent(params.term)); */
5812
						saveRemoteData[data.id].url = urlBase + separ + "sall=" + encodeURIComponent(params.term);';
5813
        }
5814
5815
        if (!$disableFiltering) {
5816
            $outdelayed .= '
5817
5818
						if(data.text.match(new RegExp(params.term))) {
5819
							return data;
5820
						}
5821
5822
						return null;';
5823
        } else {
5824
            $outdelayed .= '
5825
5826
						return data;';
5827
        }
5828
5829
        $outdelayed .= '
5830
					}
5831
				});
5832
5833
				' . ($callurlonselect ? '
5834
				/* Code to execute a GET when we select a value */
5835
				$(".' . $htmlname . '").change(function() {
5836
					var selected = $(".' . $htmlname . '").val();
5837
					console.log("We select "+selected)
5838
5839
					$(".' . $htmlname . '").val("");  /* reset visible combo value */
5840
					$.each( saveRemoteData, function( key, value ) {
5841
						if (key == selected)
5842
						{
5843
							console.log("selectArrayAjax - Do a redirect to "+value.url)
5844
							location.assign(value.url);
5845
						}
5846
					});
5847
				});' : '' ) . '
5848
5849
			});
5850
			</script>';
5851
5852
        if ($acceptdelayedhtml) {
5853
            $delayedhtmlcontent .= $outdelayed;
5854
        } else {
5855
            $out .= $outdelayed;
5856
        }
5857
        return $out;
5858
    }
5859
5860
    /**
5861
     * 	Show a multiselect form from an array.
5862
     *
5863
     * 	@param	string	$htmlname		Name of select
5864
     * 	@param	array	$array			Array with key+value
5865
     * 	@param	array	$selected		Array with key+value preselected
5866
     * 	@param	int		$key_in_label   1 pour afficher la key dans la valeur "[key] value"
5867
     * 	@param	int		$value_as_key   1 to use value as key
5868
     * 	@param  string	$morecss        Add more css style
5869
     * 	@param  int		$translate		Translate and encode value
5870
     *  @param	int		$width			Force width of select box. May be used only when using jquery couch. Example: 250, 95%
5871
     *  @param	string	$moreattrib		Add more options on select component. Example: 'disabled'
5872
     *  @param	string	$elemtype		Type of element we show ('category', ...)
5873
     *  @param	string	$placeholder	String to use as placeholder
5874
     *  @param	int		$addjscombo		Add js combo
5875
     * 	@return	string					HTML multiselect string
5876
     *  @see selectarray
5877
     */
5878
    static function multiselectarray($htmlname, $array, $selected = array(), $key_in_label = 0, $value_as_key = 0, $morecss = '', $translate = 0, $width = 0, $moreattrib = '', $elemtype = '', $placeholder = '', $addjscombo = 1)
5879
    {
5880
        global $conf, $langs;
5881
5882
        $out = '';
5883
5884
5885
        // Add code for jquery to use multiselect
5886
        if (!empty(Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT')) {
5887
            $out .= "\n" . '<!-- JS CODE TO ENABLE ' . $tmpplugin . ' for id ' . $htmlname . ' -->
5888
						<script type="text/javascript">' . "\n";
5889
            if ($addjscombo == 1) {
5890
                $tmpplugin = empty(Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT) ? constant('REQUIRE_JQUERY_MULTISELECT') : Globals::$conf->global->MAIN_USE_JQUERY_MULTISELECT;
5891
                $out .= 'function formatResult(record) {' . "\n";
5892
                if ($elemtype == 'category') {
5893
                    $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>\';
5894
									  	return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> \'+record.text+\'</span>\';';
5895
                } else {
5896
                    $out .= 'return record.text;';
5897
                }
5898
                $out .= '};' . "\n";
5899
                $out .= 'function formatSelection(record) {' . "\n";
5900
                if ($elemtype == 'category') {
5901
                    $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>\';
5902
									  	return \'<span><img src="' . DOL_URL_ROOT . '/theme/eldy/img/object_category.png' . '"> \'+record.text+\'</span>\';';
5903
                } else {
5904
                    $out .= 'return record.text;';
5905
                }
5906
                $out .= '};' . "\n";
5907
                $out .= '$(document).ready(function () {
5908
							$(\'#' . $htmlname . '\').' . $tmpplugin . '({
5909
								dir: \'ltr\',
5910
								// Specify format function for dropdown item
5911
								formatResult: formatResult,
5912
							 	templateResult: formatResult,		/* For 4.0 */
5913
								// Specify format function for selected item
5914
								formatSelection: formatSelection,
5915
							 	templateResult: formatSelection		/* For 4.0 */
5916
							});
5917
						});' . "\n";
5918
            } elseif ($addjscombo == 2) {
5919
                // Add other js lib
5920
                // ...
5921
                $out .= '$(document).ready(function () {
5922
							$(\'#' . $htmlname . '\').multiSelect({
5923
								containerHTML: \'<div class="multi-select-container">\',
5924
								menuHTML: \'<div class="multi-select-menu">\',
5925
								buttonHTML: \'<span class="multi-select-button ' . $morecss . '">\',
5926
								menuItemHTML: \'<label class="multi-select-menuitem">\',
5927
								activeClass: \'multi-select-container--open\',
5928
								noneText: \'' . $placeholder . '\'
5929
							});
5930
						})';
5931
            }
5932
            $out .= '</script>';
5933
        }
5934
5935
        // Try also magic suggest
5936
5937
        $out .= '<select id="' . $htmlname . '" class="multiselect' . ($morecss ? ' ' . $morecss : '') . '" multiple name="' . $htmlname . '[]"' . ($moreattrib ? ' ' . $moreattrib : '') . ($width ? ' style="width: ' . (preg_match('/%/', $width) ? $width : $width . 'px') . '"' : '') . '>' . "\n";
5938
        if (is_array($array) && !empty($array)) {
5939
            if ($value_as_key)
5940
                $array = array_combine($array, $array);
5941
5942
            if (!empty($array)) {
5943
                foreach ($array as $key => $value) {
5944
                    $out .= '<option value="' . $key . '"';
5945
                    if (is_array($selected) && !empty($selected) && in_array($key, $selected) && !empty($key)) {
5946
                        $out .= ' selected';
5947
                    }
5948
                    $out .= '>';
5949
5950
                    $newval = ($translate ? $langs->trans($value) : $value);
5951
                    $newval = ($key_in_label ? $key . ' - ' . $newval : $newval);
5952
                    $out .= dol_htmlentitiesbr($newval);
5953
                    $out .= '</option>' . "\n";
5954
                }
5955
            }
5956
        }
5957
        $out .= '</select>' . "\n";
5958
5959
        return $out;
5960
    }
5961
5962
    /**
5963
     * 	Show a multiselect dropbox from an array.
5964
     *
5965
     * 	@param	string	$htmlname		Name of HTML field
5966
     * 	@param	array	$array			Array with array of fields we could show. This array may be modified according to setup of user.
5967
     *  @param  string  $varpage        Id of context for page. Can be set by caller with $varpage=(empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage);
5968
     * 	@return	string					HTML multiselect string
5969
     *  @see selectarray
5970
     */
5971
    static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage)
5972
    {
5973
        global $conf, $langs, $user;
5974
5975
        if (!empty(Globals::$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
5976
            return '';
5977
5978
        $tmpvar = "MAIN_SELECTEDFIELDS_" . $varpage;
5979
        if (!empty($user->conf->$tmpvar)) {
5980
            $tmparray = explode(',', $user->conf->$tmpvar);
5981
            foreach ($array as $key => $val) {
5982
                //var_dump($key);
5983
                //var_dump($tmparray);
5984
                if (in_array($key, $tmparray))
5985
                    $array[$key]['checked'] = 1;
5986
                else
5987
                    $array[$key]['checked'] = 0;
5988
            }
5989
        }
5990
        //var_dump($array);
5991
5992
        $lis = '';
5993
        $listcheckedstring = '';
5994
5995
        foreach ($array as $key => $val) {
5996
            /* var_dump($val);
5997
              var_dump(array_key_exists('enabled', $val));
5998
              var_dump(!$val['enabled']); */
5999
            if (array_key_exists('enabled', $val) && isset($val['enabled']) && !$val['enabled']) {
6000
                unset($array[$key]);     // We don't want this field
6001
                continue;
6002
            }
6003
            if ($val['label']) {
6004
                $lis .= '<li><input type="checkbox" id="checkbox' . $key . '" value="' . $key . '"' . (empty($val['checked']) ? '' : ' checked="checked"') . '/><label for="checkbox' . $key . '">' . DolUtils::dol_escape_htmltag($langs->trans($val['label'])) . '</label></li>';
6005
                $listcheckedstring .= (empty($val['checked']) ? '' : $key . ',');
6006
            }
6007
        }
6008
6009
        $out = '<!-- Component multiSelectArrayWithCheckbox ' . $htmlname . ' -->
6010
6011
        <dl class="dropdown">
6012
            <dt>
6013
            <a href="#">
6014
              ' . img_picto('', 'list') . '
6015
            </a>
6016
            <input type="hidden" class="' . $htmlname . '" name="' . $htmlname . '" value="' . $listcheckedstring . '">
6017
            </dt>
6018
            <dd class="dropdowndd">
6019
                <div class="multiselectcheckbox' . $htmlname . '">
6020
                    <ul class="ul' . $htmlname . '">
6021
                    ' . $lis . '
6022
                    </ul>
6023
                </div>
6024
            </dd>
6025
        </dl>
6026
6027
        <script type="text/javascript">
6028
          jQuery(document).ready(function () {
6029
              $(\'.multiselectcheckbox' . $htmlname . ' input[type="checkbox"]\').on(\'click\', function () {
6030
                  console.log("A new field was added/removed")
6031
                  $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\')
6032
                  var title = $(this).val() + ",";
6033
                  if ($(this).is(\':checked\')) {
6034
                      $(\'.' . $htmlname . '\').val(title + $(\'.' . $htmlname . '\').val());
6035
                  }
6036
                  else {
6037
                      $(\'.' . $htmlname . '\').val( $(\'.' . $htmlname . '\').val().replace(title, \'\') )
6038
                  }
6039
                  // Now, we submit page
6040
                  $(this).parents(\'form:first\').submit();
6041
              });
6042
           });
6043
        </script>
6044
6045
        ';
6046
        return $out;
6047
    }
6048
6049
    /**
6050
     * 	Render list of categories linked to object with id $id and type $type
6051
     *
6052
     * 	@param		int		$id				Id of object
6053
     * 	@param		string	$type			Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
6054
     *  @param		int		$rendermode		0=Default, use multiselect. 1=Emulate multiselect (recommended)
6055
     * 	@return		string					String with categories
6056
     */
6057
    function showCategories($id, $type, $rendermode = 0)
6058
    {
6059
        global $db;
6060
6061
        include_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
6062
6063
        $cat = new Categorie($db);
6064
        $categories = $cat->containing($id, $type);
6065
6066
        if ($rendermode == 1) {
6067
            $toprint = array();
6068
            foreach ($categories as $c) {
6069
                $ways = $c->print_all_ways();       // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text
6070
                foreach ($ways as $way) {
6071
                    $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"' . ($c->color ? ' style="background: #' . $c->color . ';"' : ' style="background: #aaa"') . '>' . img_object('', 'category') . ' ' . $way . '</li>';
6072
                }
6073
            }
6074
            return '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
6075
        }
6076
6077
        if ($rendermode == 0) {
6078
            $cate_arbo = $this->select_all_categories($type, '', 'parent', 64, 0, 1);
6079
            foreach ($categories as $c) {
6080
                $arrayselected[] = $c->id;
6081
            }
6082
6083
            return $this->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%', 'disabled', 'category');
6084
        }
6085
6086
        return 'ErrorBadValueForParameterRenderMode'; // Should not happened
6087
    }
6088
6089
    /**
6090
     *  Show linked object block.
6091
     *
6092
     *  @param	CommonObject	$object		      Object we want to show links to
6093
     *  @param  string          $morehtmlright    More html to show on right of title
6094
     *  @param  array           $compatibleImportElementsList  Array of compatibles elements object for "import from" action
6095
     *  @return	int							      <0 if KO, >=0 if OK
6096
     */
6097
    function showLinkedObjectBlock($object, $morehtmlright = '', $compatibleImportElementsList = false)
6098
    {
6099
        global $conf, $langs, $hookmanager;
6100
        global $bc;
6101
6102
        $object->fetchObjectLinked();
6103
6104
        // Bypass the default method
6105
        $hookmanager->initHooks(array('commonobject'));
6106
        $parameters = array(
6107
            'morehtmlright' => $morehtmlright,
6108
            'compatibleImportElementsList' => & $compatibleImportElementsList,
6109
        );
6110
        $reshook = $hookmanager->executeHooks('showLinkedObjectBlock', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
6111
6112
        if (empty($reshook)) {
6113
            $nbofdifferenttypes = count($object->linkedObjects);
6114
6115
            print '<!-- showLinkedObjectBlock -->';
6116
            print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock');
6117
6118
6119
            print '<div class="div-table-responsive-no-min">';
6120
            print '<table class="noborder allwidth" data-block="showLinkedObject" data-element="' . $object->element . '"  data-elementid="' . $object->id . '"   >';
6121
6122
            print '<tr class="liste_titre">';
6123
            print '<td>' . $langs->trans("Type") . '</td>';
6124
            print '<td>' . $langs->trans("Ref") . '</td>';
6125
            print '<td align="center"></td>';
6126
            print '<td align="center">' . $langs->trans("Date") . '</td>';
6127
            print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
6128
            print '<td align="right">' . $langs->trans("Status") . '</td>';
6129
            print '<td></td>';
6130
            print '</tr>';
6131
6132
            $nboftypesoutput = 0;
6133
6134
            foreach ($object->linkedObjects as $objecttype => $objects) {
6135
                $tplpath = $element = $subelement = $objecttype;
6136
6137
                // to display inport button on tpl
6138
                $showImportButton = false;
6139
                if (!empty($compatibleImportElementsList) && in_array($element, $compatibleImportElementsList)) {
6140
                    $showImportButton = true;
6141
                }
6142
6143
                if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i', $objecttype, $regs)) {
6144
                    $element = $regs[1];
6145
                    $subelement = $regs[2];
6146
                    $tplpath = $element . '/' . $subelement;
6147
                }
6148
                $tplname = 'linkedobjectblock';
6149
6150
                // To work with non standard path
6151
                if ($objecttype == 'facture') {
6152
                    $tplpath = 'compta/' . $element;
6153
                    if (empty(Globals::$conf->facture->enabled))
6154
                        continue; // Do not show if module disabled
6155
                }
6156
                else if ($objecttype == 'facturerec') {
6157
                    $tplpath = 'compta/facture';
6158
                    $tplname = 'linkedobjectblockForRec';
6159
                    if (empty(Globals::$conf->facture->enabled))
6160
                        continue; // Do not show if module disabled
6161
                }
6162
                else if ($objecttype == 'propal') {
6163
                    $tplpath = 'comm/' . $element;
6164
                    if (empty(Globals::$conf->propal->enabled))
6165
                        continue; // Do not show if module disabled
6166
                }
6167
                else if ($objecttype == 'supplier_proposal') {
6168
                    if (empty(Globals::$conf->supplier_proposal->enabled))
6169
                        continue; // Do not show if module disabled
6170
                }
6171
                else if ($objecttype == 'shipping' || $objecttype == 'shipment') {
6172
                    $tplpath = 'expedition';
6173
                    if (empty(Globals::$conf->expedition->enabled))
6174
                        continue; // Do not show if module disabled
6175
                }
6176
                else if ($objecttype == 'reception') {
6177
                    $tplpath = 'reception';
6178
                    if (empty(Globals::$conf->reception->enabled))
6179
                        continue; // Do not show if module disabled
6180
                }
6181
                else if ($objecttype == 'delivery') {
6182
                    $tplpath = 'livraison';
6183
                    if (empty(Globals::$conf->expedition->enabled))
6184
                        continue; // Do not show if module disabled
6185
                }
6186
                else if ($objecttype == 'invoice_supplier') {
6187
                    $tplpath = 'fourn/facture';
6188
                } else if ($objecttype == 'order_supplier') {
6189
                    $tplpath = 'fourn/commande';
6190
                } else if ($objecttype == 'expensereport') {
6191
                    $tplpath = 'expensereport';
6192
                } else if ($objecttype == 'subscription') {
6193
                    $tplpath = 'adherents';
6194
                }
6195
6196
                global $linkedObjectBlock;
6197
                $linkedObjectBlock = $objects;
6198
6199
6200
                // Output template part (modules that overwrite templates must declare this into descriptor)
6201
                $dirtpls = array_merge(Globals::$conf->modules_parts['tpl'], array('/' . $tplpath . '/tpl'));
6202
                foreach ($dirtpls as $reldir) {
6203
                    if ($nboftypesoutput == ($nbofdifferenttypes - 1)) {    // No more type to show after
6204
                        global $noMoreLinkedObjectBlockAfter;
6205
                        $noMoreLinkedObjectBlockAfter = 1;
6206
                    }
6207
6208
                    $res = @include dol_buildpath($reldir . '/' . $tplname . '.tpl.php');
6209
                    if ($res) {
6210
                        $nboftypesoutput++;
6211
                        break;
6212
                    }
6213
                }
6214
            }
6215
6216
            if (!$nboftypesoutput) {
6217
                print '<tr><td class="impair opacitymedium" colspan="7">' . $langs->trans("None") . '</td></tr>';
6218
            }
6219
6220
            print '</table>';
6221
6222
            if (!empty($compatibleImportElementsList)) {
6223
                $res = @include dol_buildpath('core/tpl/ajax/objectlinked_lineimport.tpl.php');
6224
            }
6225
6226
6227
            print '</div>';
6228
6229
            return $nbofdifferenttypes;
6230
        }
6231
    }
6232
6233
    /**
6234
     *  Show block with links to link to other objects.
6235
     *
6236
     *  @param	CommonObject	$object				Object we want to show links to
6237
     *  @param	array			$restrictlinksto	Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction.
6238
     *  @param	array			$excludelinksto		Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion.
6239
     *  @return	string								<0 if KO, >0 if OK
6240
     */
6241
    function showLinkToObjectBlock($object, $restrictlinksto = array(), $excludelinksto = array())
6242
    {
6243
        global $conf, $langs, $hookmanager;
6244
        global $bc;
6245
6246
        $linktoelem = '';
6247
        $linktoelemlist = '';
6248
        $listofidcompanytoscan = '';
6249
6250
        if (!is_object($object->thirdparty))
6251
            $object->fetch_thirdparty();
6252
6253
        $possiblelinks = array();
6254
        if (is_object($object->thirdparty) && !empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
6255
            $listofidcompanytoscan = $object->thirdparty->id;
6256
            if (($object->thirdparty->parent > 0) && !empty(Globals::$conf->global->THIRDPARTY_INCLUDE_PARENT_IN_LINKTO))
6257
                $listofidcompanytoscan .= ',' . $object->thirdparty->parent;
6258
            if (($object->fk_project > 0) && !empty(Globals::$conf->global->THIRDPARTY_INCLUDE_PROJECT_THIRDPARY_IN_LINKTO)) {
6259
                include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
6260
                $tmpproject = new Project($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6261
                $tmpproject->fetch($object->fk_project);
6262
                if ($tmpproject->socid > 0 && ($tmpproject->socid != $object->thirdparty->id))
6263
                    $listofidcompanytoscan .= ',' . $tmpproject->socid;
6264
                unset($tmpproject);
6265
            }
6266
6267
            $possiblelinks = array(
6268
                'propal' => array('enabled' => Globals::$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') . ')'),
6269
                'order' => array('enabled' => Globals::$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') . ')'),
6270
                'invoice' => array('enabled' => Globals::$conf->facture->enabled, 'perms' => 1, 'label' => 'LinkToInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total as total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('invoice') . ')'),
6271
                'invoice_template' => array('enabled' => Globals::$conf->facture->enabled, 'perms' => 1, 'label' => 'LinkToTemplateInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total as total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('invoice') . ')'),
6272
                'contrat' => array('enabled' => Globals::$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') . ')'),
6273
                'fichinter' => array('enabled' => Globals::$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') . ')'),
6274
                'supplier_proposal' => array('enabled' => Globals::$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') . ')'),
6275
                'order_supplier' => array('enabled' => Globals::$conf->supplier_order->enabled, 'perms' => 1, 'label' => 'LinkToSupplierOrder', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('commande_fournisseur') . ')'),
6276
                'invoice_supplier' => array('enabled' => Globals::$conf->supplier_invoice->enabled, 'perms' => 1, 'label' => 'LinkToSupplierInvoice', 'sql' => "SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . MAIN_DB_PREFIX . "societe as s, " . MAIN_DB_PREFIX . "facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $listofidcompanytoscan . ') AND t.entity IN (' . getEntity('facture_fourn') . ')')
6277
            );
6278
        }
6279
6280
        global $action;
6281
6282
        // Can complete the possiblelink array
6283
        $hookmanager->initHooks(array('commonobject'));
6284
        $parameters = array('listofidcompanytoscan' => $listofidcompanytoscan);
6285
        $reshook = $hookmanager->executeHooks('showLinkToObjectBlock', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
6286
        if (empty($reshook)) {
6287
            if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
6288
                $possiblelinks = array_merge($possiblelinks, $hookmanager->resArray);
6289
            }
6290
        } else if ($reshook > 0) {
6291
            if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
6292
                $possiblelinks = $hookmanager->resArray;
6293
            }
6294
        }
6295
6296
        foreach ($possiblelinks as $key => $possiblelink) {
6297
            $num = 0;
6298
6299
            if (empty($possiblelink['enabled']))
6300
                continue;
6301
6302
            if (!empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) {
6303
                print '<div id="' . $key . 'list"' . (empty(Globals::$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display:none"' : '') . '>';
6304
                $sql = $possiblelink['sql'];
6305
6306
                $resqllist = $this->db->query($sql);
6307
                if ($resqllist) {
6308
                    $num = $this->db->num_rows($resqllist);
6309
                    $i = 0;
6310
6311
                    print '<br><form action="' . $_SERVER["PHP_SELF"] . '" method="POST" name="formlinked' . $key . '">';
6312
                    print '<input type="hidden" name="id" value="' . $object->id . '">';
6313
                    print '<input type="hidden" name="action" value="addlink">';
6314
                    print '<input type="hidden" name="addlink" value="' . $key . '">';
6315
                    print '<table class="noborder">';
6316
                    print '<tr class="liste_titre">';
6317
                    print '<td class="nowrap"></td>';
6318
                    print '<td align="center">' . $langs->trans("Ref") . '</td>';
6319
                    print '<td align="left">' . $langs->trans("RefCustomer") . '</td>';
6320
                    print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
6321
                    print '<td align="left">' . $langs->trans("Company") . '</td>';
6322
                    print '</tr>';
6323
                    while ($i < $num) {
6324
                        $objp = $this->db->fetch_object($resqllist);
6325
6326
                        print '<tr class="oddeven">';
6327
                        print '<td aling="left">';
6328
                        print '<input type="radio" name="idtolinkto" value=' . $objp->rowid . '>';
6329
                        print '</td>';
6330
                        print '<td align="center">' . $objp->ref . '</td>';
6331
                        print '<td>' . $objp->ref_client . '</td>';
6332
                        print '<td align="right">' . price($objp->total_ht) . '</td>';
6333
                        print '<td>' . $objp->name . '</td>';
6334
                        print '</tr>';
6335
                        $i++;
6336
                    }
6337
                    print '</table>';
6338
                    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>';
6339
6340
                    print '</form>';
6341
                    $this->db->free($resqllist);
6342
                } else {
6343
                    DolUtils::dol_print_error($this->db);
6344
                }
6345
                print '</div>';
6346
                if ($num > 0) {
6347
6348
                }
6349
6350
                //$linktoelem.=($linktoelem?' &nbsp; ':'');
6351
                if ($num > 0)
6352
                    $linktoelemlist .= '<li><a href="#linkto' . $key . '" class="linkto dropdowncloseonclick" rel="' . $key . '">' . $langs->trans($possiblelink['label']) . ' (' . $num . ')</a></li>';
6353
                //else $linktoelem.=$langs->trans($possiblelink['label']);
6354
                else
6355
                    $linktoelemlist .= '<li><span class="linktodisabled">' . $langs->trans($possiblelink['label']) . ' (0)</span></li>';
6356
            }
6357
        }
6358
6359
        if ($linktoelemlist) {
6360
            $linktoelem = '
6361
    		<dl class="dropdown" id="linktoobjectname">
6362
    		<dt><a href="#linktoobjectname">' . $langs->trans("LinkTo") . '...</a></dt>
6363
    		<dd>
6364
    		<div class="multiselectlinkto">
6365
    		<ul class="ulselectedfields">' . $linktoelemlist . '
6366
    		</ul>
6367
    		</div>
6368
    		</dd>
6369
    		</dl>';
6370
        } else {
6371
            $linktoelem = '';
6372
        }
6373
6374
        print '<!-- Add js to show linkto box -->
6375
				<script type="text/javascript" language="javascript">
6376
				jQuery(document).ready(function() {
6377
					jQuery(".linkto").click(function() {
6378
						console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\'));
6379
					    jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
6380
						jQuery(this).toggle();
6381
					});
6382
				});
6383
				</script>
6384
		';
6385
6386
        return $linktoelem;
6387
    }
6388
6389
    /**
6390
     * 	Return an html string with a select combo box to choose yes or no
6391
     *
6392
     * 	@param	string		$htmlname		Name of html select field
6393
     * 	@param	string		$value			Pre-selected value
6394
     * 	@param	int			$option			0 return yes/no, 1 return 1/0
6395
     * 	@param	bool		$disabled		true or false
6396
     *  @param	int      	$useempty		1=Add empty line
6397
     * 	@return	string						See option
6398
     */
6399
    function selectyesno($htmlname, $value = '', $option = 0, $disabled = false, $useempty = 0)
6400
    {
6401
        global $langs;
6402
6403
        $yes = "yes";
6404
        $no = "no";
6405
        if ($option) {
6406
            $yes = "1";
6407
            $no = "0";
6408
        }
6409
6410
        $disabled = ($disabled ? ' disabled' : '');
6411
6412
        $resultyesno = '<select class="flat width75" id="' . $htmlname . '" name="' . $htmlname . '"' . $disabled . '>' . "\n";
6413
        if ($useempty)
6414
            $resultyesno .= '<option value="-1"' . (($value < 0) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
6415
        if (("$value" == 'yes') || ($value == 1)) {
6416
            $resultyesno .= '<option value="' . $yes . '" selected>' . $langs->trans("Yes") . '</option>' . "\n";
6417
            $resultyesno .= '<option value="' . $no . '">' . $langs->trans("No") . '</option>' . "\n";
6418
        } else {
6419
            $selected = (($useempty && $value != '0' && $value != 'no') ? '' : ' selected');
6420
            $resultyesno .= '<option value="' . $yes . '">' . $langs->trans("Yes") . '</option>' . "\n";
6421
            $resultyesno .= '<option value="' . $no . '"' . $selected . '>' . $langs->trans("No") . '</option>' . "\n";
6422
        }
6423
        $resultyesno .= '</select>' . "\n";
6424
        return $resultyesno;
6425
    }
6426
6427
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
6428
    /**
6429
     *  Return list of export templates
6430
     *
6431
     *  @param	string	$selected          Id modele pre-selectionne
6432
     *  @param  string	$htmlname          Name of HTML select
6433
     *  @param  string	$type              Type of searched templates
6434
     *  @param  int		$useempty          Affiche valeur vide dans liste
6435
     *  @return	void
6436
     */
6437
    function select_export_model($selected = '', $htmlname = 'exportmodelid', $type = '', $useempty = 0)
6438
    {
6439
        // phpcs:enable
6440
        $sql = "SELECT rowid, label";
6441
        $sql .= " FROM " . MAIN_DB_PREFIX . "export_model";
6442
        $sql .= " WHERE type = '" . $type . "'";
6443
        $sql .= " ORDER BY rowid";
6444
        $result = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6445
        if ($result) {
6446
            print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
6447
            if ($useempty) {
6448
                print '<option value="-1">&nbsp;</option>';
6449
            }
6450
6451
            $num = $this->db->num_rows($result);
6452
            $i = 0;
6453
            while ($i < $num) {
6454
                $obj = $this->db->fetch_object($result);
6455
                if ($selected == $obj->rowid) {
6456
                    print '<option value="' . $obj->rowid . '" selected>';
6457
                } else {
6458
                    print '<option value="' . $obj->rowid . '">';
6459
                }
6460
                print $obj->label;
6461
                print '</option>';
6462
                $i++;
6463
            }
6464
            print "</select>";
6465
        } else {
6466
            DolUtils::dol_print_error($this->db);
6467
        }
6468
    }
6469
6470
    /**
6471
     *    Return a HTML area with the reference of object and a navigation bar for a business object
6472
     *    Note: To complete search with a particular filter on select, you can set $object->next_prev_filter set to define SQL criterias.
6473
     *
6474
     *    @param	object	$object			Object to show.
6475
     *    @param	string	$paramid   		Name of parameter to use to name the id into the URL next/previous link.
6476
     *    @param	string	$morehtml  		More html content to output just before the nav bar.
6477
     *    @param	int		$shownav	  	Show Condition (navigation is shown if value is 1).
6478
     *    @param	string	$fieldid   		Name of field id into database to use for select next and previous (we make the select max and min on this field compared to $object->ref). Use 'none' to disable next/prev.
6479
     *    @param	string	$fieldref   	Name of field ref of object (object->ref) to show or 'none' to not show ref.
6480
     *    @param	string	$morehtmlref  	More html to show after ref.
6481
     *    @param	string	$moreparam  	More param to add in nav link url. Must start with '&...'.
6482
     * 	  @param	int		$nodbprefix		Do not include DB prefix to forge table name.
6483
     * 	  @param	string	$morehtmlleft	More html code to show before ref.
6484
     * 	  @param	string	$morehtmlstatus	More html code to show under navigation arrows (status place).
6485
     * 	  @param	string	$morehtmlright	More html code to show after ref.
6486
     * 	  @return	string    				Portion HTML with ref + navigation buttons
6487
     */
6488
    function showrefnav($object, $paramid, $morehtml = '', $shownav = 1, $fieldid = 'rowid', $fieldref = 'ref', $morehtmlref = '', $moreparam = '', $nodbprefix = 0, $morehtmlleft = '', $morehtmlstatus = '', $morehtmlright = '')
6489
    {
6490
        global $langs, $conf, $hookmanager;
6491
6492
        $ret = '';
6493
        if (empty($fieldid))
6494
            $fieldid = 'rowid';
6495
        if (empty($fieldref))
6496
            $fieldref = 'ref';
6497
6498
        // Add where from hooks
6499
        if (is_object($hookmanager)) {
6500
            $parameters = array();
6501
            $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object);    // Note that $action and $object may have been modified by hook
6502
            $object->next_prev_filter .= $hookmanager->resPrint;
6503
        }
6504
        $previous_ref = $next_ref = '';
6505
        if ($shownav) {
6506
            //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam";
6507
            $object->load_previous_next_ref((isset($object->next_prev_filter) ? $object->next_prev_filter : ''), $fieldid, $nodbprefix);
6508
6509
            $navurl = $_SERVER["PHP_SELF"];
6510
            // Special case for project/task page
6511
            if ($paramid == 'project_ref') {
6512
                $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/', '/tasks.php', $navurl);
6513
                $paramid = 'ref';
6514
            }
6515
6516
            // accesskey is for Windows or Linux:  ALT + key for chrome, ALT + SHIFT + KEY for firefox
6517
            // accesskey is for Mac:               CTRL + key for all browsers
6518
            $stringforfirstkey = $langs->trans("KeyboardShortcut");
6519
            if (Globals::$conf->browser->name == 'chrome') {
6520
                $stringforfirstkey .= ' ALT +';
6521
            } elseif (Globals::$conf->browser->name == 'firefox') {
6522
                $stringforfirstkey .= ' ALT + SHIFT +';
6523
            } else {
6524
                $stringforfirstkey .= ' CTL +';
6525
            }
6526
6527
            $previous_ref = $object->ref_previous ? '<a accesskey="p" title="' . $stringforfirstkey . ' p" class="classfortooltip" href="' . $navurl . '?' . $paramid . '=' . urlencode($object->ref_previous) . $moreparam . '"><i class="fa fa-chevron-left"></i></a>' : '<span class="inactive"><i class="fa fa-chevron-left opacitymedium"></i></span>';
6528
            $next_ref = $object->ref_next ? '<a accesskey="n" title="' . $stringforfirstkey . ' n" class="classfortooltip" href="' . $navurl . '?' . $paramid . '=' . urlencode($object->ref_next) . $moreparam . '"><i class="fa fa-chevron-right"></i></a>' : '<span class="inactive"><i class="fa fa-chevron-right opacitymedium"></i></span>';
6529
        }
6530
6531
        //print "xx".$previous_ref."x".$next_ref;
6532
        $ret .= '<!-- Start banner content --><div style="vertical-align: middle">';
6533
6534
        // Right part of banner
6535
        if ($morehtmlright)
6536
            $ret .= '<div class="inline-block floatleft">' . $morehtmlright . '</div>';
6537
6538
        if ($previous_ref || $next_ref || $morehtml) {
6539
            $ret .= '<div class="pagination paginationref"><ul class="right">';
6540
        }
6541
        if ($morehtml) {
6542
            $ret .= '<li class="noborder litext">' . $morehtml . '</li>';
6543
        }
6544
        if ($shownav && ($previous_ref || $next_ref)) {
6545
            $ret .= '<li class="pagination">' . $previous_ref . '</li>';
6546
            $ret .= '<li class="pagination">' . $next_ref . '</li>';
6547
        }
6548
        if ($previous_ref || $next_ref || $morehtml) {
6549
            $ret .= '</ul></div>';
6550
        }
6551
6552
        $parameters = array();
6553
        $reshook = $hookmanager->executeHooks('moreHtmlStatus', $parameters, $object);    // Note that $action and $object may have been modified by hook
6554
        if (empty($reshook))
6555
            $morehtmlstatus .= $hookmanager->resPrint;
6556
        else
6557
            $morehtmlstatus = $hookmanager->resPrint;
6558
        if ($morehtmlstatus)
6559
            $ret .= '<div class="statusref">' . $morehtmlstatus . '</div>';
6560
6561
        $parameters = array();
6562
        $reshook = $hookmanager->executeHooks('moreHtmlRef', $parameters, $object); // Note that $action and $object may have been modified by hook
6563
        if (empty($reshook))
6564
            $morehtmlref .= $hookmanager->resPrint;
6565
        elseif ($reshook > 0)
6566
            $morehtmlref = $hookmanager->resPrint;
6567
6568
        // Left part of banner
6569
        if ($morehtmlleft) {
6570
            if (Globals::$conf->browser->layout == 'phone')
6571
                $ret .= '<div class="floatleft">' . $morehtmlleft . '</div>';    // class="center" to have photo in middle
6572
            else
6573
                $ret .= '<div class="inline-block floatleft">' . $morehtmlleft . '</div>';
6574
        }
6575
6576
        //if (Globals::$conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>';
6577
        $ret .= '<div class="inline-block floatleft valignmiddle refid' . (($shownav && ($previous_ref || $next_ref)) ? ' refidpadding' : '') . '">';
6578
6579
        // For thirdparty, contact, user, member, the ref is the id, so we show something else
6580
        if ($object->element == 'societe') {
6581
            $ret .= dol_htmlentities($object->name);
6582
        } else if ($object->element == 'member') {
6583
            $ret .= $object->ref . '<br>';
6584
            $fullname = $object->getFullName($langs);
6585
            if ($object->morphy == 'mor' && $object->societe) {
6586
                $ret .= dol_htmlentities($object->societe) . ((!empty($fullname) && $object->societe != $fullname) ? ' (' . dol_htmlentities($fullname) . ')' : '');
6587
            } else {
6588
                $ret .= dol_htmlentities($fullname) . ((!empty($object->societe) && $object->societe != $fullname) ? ' (' . dol_htmlentities($object->societe) . ')' : '');
6589
            }
6590
        } else if (in_array($object->element, array('contact', 'user', 'usergroup'))) {
6591
            $ret .= dol_htmlentities($object->getFullName($langs));
6592
        } else if (in_array($object->element, array('action', 'agenda'))) {
6593
            $ret .= $object->ref . '<br>' . $object->label;
6594
        } else if (in_array($object->element, array('adherent_type'))) {
6595
            $ret .= $object->label;
6596
        } else if ($object->element == 'ecm_directories') {
6597
            $ret .= '';
6598
        } else if ($fieldref != 'none')
6599
            $ret .= dol_htmlentities($object->$fieldref);
6600
6601
6602
        if ($morehtmlref) {
6603
            $ret .= ' ' . $morehtmlref;
6604
        }
6605
        $ret .= '</div>';
6606
6607
        $ret .= '</div><!-- End banner content -->';
6608
6609
        return $ret;
6610
    }
6611
6612
    /**
6613
     *    	Return HTML code to output a barcode
6614
     *
6615
     *     	@param	Object	$object		Object containing data to retrieve file name
6616
     * 		@param	int		$width			Width of photo
6617
     * 	  	@return string    				HTML code to output barcode
6618
     */
6619
    function showbarcode(&$object, $width = 100)
6620
    {
6621
        global $conf;
6622
6623
        //Check if barcode is filled in the card
6624
        if (empty($object->barcode))
6625
            return '';
6626
6627
        // Complete object if not complete
6628
        if (empty($object->barcode_type_code) || empty($object->barcode_type_coder)) {
6629
            $result = $object->fetch_barcode();
6630
            //Check if fetch_barcode() failed
6631
            if ($result < 1)
6632
                return '<!-- ErrorFetchBarcode -->';
6633
        }
6634
6635
        // Barcode image
6636
        $url = DOL_URL_ROOT . '/viewimage.php?modulepart=barcode&generator=' . urlencode($object->barcode_type_coder) . '&code=' . urlencode($object->barcode) . '&encoding=' . urlencode($object->barcode_type_code);
6637
        $out = '<!-- url barcode = ' . $url . ' -->';
6638
        $out .= '<img src="' . $url . '">';
6639
        return $out;
6640
    }
6641
6642
    /**
6643
     *    	Return HTML code to output a photo
6644
     *
6645
     *    	@param	string		$modulepart			Key to define module concerned ('societe', 'userphoto', 'memberphoto')
6646
     *     	@param  object		$object				Object containing data to retrieve file name
6647
     * 		@param	int			$width				Width of photo
6648
     * 		@param	int			$height				Height of photo (auto if 0)
6649
     * 		@param	int			$caneditfield		Add edit fields
6650
     * 		@param	string		$cssclass			CSS name to use on img for photo
6651
     * 		@param	string		$imagesize		    'mini', 'small' or '' (original)
6652
     *      @param  int         $addlinktofullsize  Add link to fullsize image
6653
     *      @param  int         $cache              1=Accept to use image in cache
6654
     *      @param	string		$forcecapture		Force parameter capture on HTML input file element to ask a smartphone to allow to open camera to take photo. Auto if empty.
6655
     * 	  	@return string    						HTML code to output photo
6656
     */
6657
    static function showphoto($modulepart, $object, $width = 100, $height = 0, $caneditfield = 0, $cssclass = 'photowithmargin', $imagesize = '', $addlinktofullsize = 1, $cache = 0, $forcecapture = '')
6658
    {
6659
        $entity = (!empty($object->entity) ? $object->entity : Globals::$conf->entity);
6660
        $id = (!empty($object->id) ? $object->id : $object->rowid);
6661
6662
        $ret = '';
6663
        $dir = '';
6664
        $file = '';
6665
        $originalfile = '';
6666
        $altfile = '';
6667
        $email = '';
6668
        $capture = '';
6669
        if ($modulepart == 'societe') {
6670
            $dir = Globals::$conf->societe->multidir_output[$entity];
6671
            if (!empty($object->logo)) {
6672
                if ((string) $imagesize == 'mini') {
6673
                    $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . getImageFileNameForSize($object->logo, '_mini');             // getImageFileNameForSize include the thumbs
6674
                } else {
6675
                    if ((string) $imagesize == 'small') {
6676
                        $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . getImageFileNameForSize($object->logo, '_small');
6677
                    } else {
6678
                        $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . $object->logo;
6679
                    }
6680
                }
6681
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'thirdparty') . '/logos/' . $object->logo;
6682
            }
6683
            $email = $object->email;
6684
        } else if ($modulepart == 'contact') {
6685
            $dir = Globals::$conf->societe->multidir_output[$entity] . '/contact';
6686
            if (!empty($object->photo)) {
6687
                if ((string) $imagesize == 'mini') {
6688
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . getImageFileNameForSize($object->photo, '_mini');
6689
                } else if ((string) $imagesize == 'small') {
6690
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . getImageFileNameForSize($object->photo, '_small');
6691
                } else {
6692
                    $file = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . $object->photo;
6693
                }
6694
                $originalfile = get_exdir(0, 0, 0, 0, $object, 'contact') . '/photos/' . $object->photo;
6695
            }
6696
            $email = $object->email;
6697
            $capture = 'user';
6698
        } else {
6699
            if ($modulepart == 'userphoto') {
6700
                $dir = Globals::$conf->user->dir_output ?? (DOL_BASE_URI . '/users');
6701
                if (!empty($object->photo)) {
6702
                    if ((string) $imagesize == 'mini') {
6703
                        $file = get_exdir(0, 0, 0, 0, $object, 'user') . $object->id . '/' . getImageFileNameForSize($object->photo, '_mini');
6704
                    } else if ((string) $imagesize == 'small') {
6705
                        $file = get_exdir(0, 0, 0, 0, $object, 'user') . $object->id . '/' . getImageFileNameForSize($object->photo, '_small');
6706
                    } else {
6707
                        $file = get_exdir(0, 0, 0, 0, $object, 'user') . '/' . $object->id . '/' . $object->photo;
6708
                    }
6709
                    $originalfile = get_exdir(0, 0, 0, 0, $object, 'user') . '/' . $object->id . '/' . $object->photo;
6710
                }
6711
                if (!empty(Globals::$conf->global->MAIN_OLD_IMAGE_LINKS)) {
6712
                    $altfile = $object->id . ".jpg"; // For backward compatibility
6713
                }
6714
                $email = $object->email;
6715
                $capture = 'user';
6716
            } else {
6717
                if ($modulepart == 'memberphoto') {
6718
                    $dir = Globals::$conf->adherent->dir_output;
6719
                    if (!empty($object->photo)) {
6720
                        if ((string) $imagesize == 'mini')
6721
                            $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_mini');
6722
                        else if ((string) $imagesize == 'small')
6723
                            $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . getImageFileNameForSize($object->photo, '_small');
6724
                        else
6725
                            $file = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo;
6726
                        $originalfile = get_exdir(0, 0, 0, 0, $object, 'member') . 'photos/' . $object->photo;
6727
                    }
6728
                    if (!empty(Globals::$conf->global->MAIN_OLD_IMAGE_LINKS))
6729
                        $altfile = $object->id . ".jpg"; // For backward compatibility
6730
                    $email = $object->email;
6731
                    $capture = 'user';
6732
                }
6733
                else {
6734
                    // Generic case to show photos
6735
                    $dir = Globals::$conf->$modulepart->dir_output;
6736
                    if (!empty($object->photo)) {
6737
                        if ((string) $imagesize == 'mini')
6738
                            $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . getImageFileNameForSize($object->photo, '_mini');
6739
                        else if ((string) $imagesize == 'small')
6740
                            $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . getImageFileNameForSize($object->photo, '_small');
6741
                        else
6742
                            $file = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . $object->photo;
6743
                        $originalfile = get_exdir($id, 2, 0, 0, $object, $modulepart) . 'photos/' . $object->photo;
6744
                    }
6745
                    if (!empty(Globals::$conf->global->MAIN_OLD_IMAGE_LINKS))
6746
                        $altfile = $object->id . ".jpg"; // For backward compatibility
6747
                    $email = $object->email;
6748
                }
6749
            }
6750
        }
6751
        if ($forcecapture)
6752
            $capture = $forcecapture;
6753
6754
        if ($dir) {
6755
            if ($file && file_exists($dir . "/" . $file)) {
6756
                if ($addlinktofullsize) {
6757
                    $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity=' . $entity);
6758
                    if ($urladvanced)
6759
                        $ret .= '<a href="' . $urladvanced . '">';
6760
                    else
6761
                        $ret .= '<a href="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($originalfile) . '&cache=' . $cache . '">';
6762
                }
6763
                $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 . '">';
6764
                if ($addlinktofullsize)
6765
                    $ret .= '</a>';
6766
            }
6767
            else if ($altfile && file_exists($dir . "/" . $altfile)) {
6768
                if ($addlinktofullsize) {
6769
                    $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 0, '&entity=' . $entity);
6770
                    if ($urladvanced)
6771
                        $ret .= '<a href="' . $urladvanced . '">';
6772
                    else
6773
                        $ret .= '<a href="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($originalfile) . '&cache=' . $cache . '">';
6774
                }
6775
                $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 . '">';
6776
                if ($addlinktofullsize)
6777
                    $ret .= '</a>';
6778
            }
6779
            else {
6780
                $nophoto = '/public/theme/common/nophoto.png';
6781
                if (in_array($modulepart, array('userphoto', 'contact'))) { // For module that are "physical" users
6782
                    $nophoto = '/public/theme/common/user_anonymous.png';
6783
                    if ($object->gender == 'man') {
6784
                        $nophoto = '/public/theme/common/user_man.png';
6785
                    }
6786
                    if ($object->gender == 'woman') {
6787
                        $nophoto = '/public/theme/common/user_woman.png';
6788
                    }
6789
                }
6790
6791
                if (!empty(Globals::$conf->gravatar->enabled) && $email) {
6792
                    /**
6793
                     * @see https://gravatar.com/site/implement/images/php/
6794
                     */
6795
                    global $dolibarr_main_url_root;
6796
                    $ret .= '<!-- Put link to gravatar -->';
6797
                    //$defaultimg=urlencode(dol_buildpath($nophoto,3));
6798
                    $defaultimg = 'mm';
6799
                    $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
6800
                } else {
6801
                    //$ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_URL_ROOT . $nophoto . '">';
6802
                    $ret .= '<img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" ' . ($width ? ' width="' . $width . '"' : '') . ($height ? ' height="' . $height . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '">';
6803
                }
6804
            }
6805
6806
            if ($caneditfield) {
6807
                if ($object->photo) {
6808
                    $ret .= "<br>\n";
6809
                }
6810
                $ret .= '<table class="nobordernopadding centpercent">';
6811
                if ($object->photo) {
6812
                    $ret .= '<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> ' . $langs->trans("Delete") . '<br><br></td></tr>';
6813
                }
6814
                $ret .= '<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"' . ($capture ? ' capture="' . $capture . '"' : '') . '></td></tr>';
6815
                $ret .= '</table>';
6816
            }
6817
        } else
6818
            DolUtils::dol_print_error('', 'Call of showphoto with wrong parameters modulepart=' . $modulepart);
6819
6820
        return $ret;
6821
    }
6822
6823
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
6824
    /**
6825
     * 	Return select list of groups
6826
     *
6827
     *  @param	string	$selected       Id group preselected
6828
     *  @param  string	$htmlname       Field name in form
6829
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
6830
     *  @param  string	$exclude        Array list of groups id to exclude
6831
     * 	@param	int		$disabled		If select list must be disabled
6832
     *  @param  string	$include        Array list of groups id to include
6833
     * 	@param	int		$enableonly		Array list of groups id to be enabled. All other must be disabled
6834
     * 	@param	string	$force_entity	'0' or Ids of environment to force
6835
     * 	@param	bool	$multiple		add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
6836
     *  @return	string
6837
     *  @see select_dolusers
6838
     */
6839
    function select_dolgroups($selected = '', $htmlname = 'groupid', $show_empty = 0, $exclude = '', $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $multiple = false)
6840
    {
6841
        // phpcs:enable
6842
        global $conf, $user, $langs;
6843
6844
        // Permettre l'exclusion de groupes
6845
        if (is_array($exclude))
6846
            $excludeGroups = implode("','", $exclude);
6847
        // Permettre l'inclusion de groupes
6848
        if (is_array($include))
6849
            $includeGroups = implode("','", $include);
6850
6851
        if (!is_array($selected))
6852
            $selected = array($selected);
6853
6854
        $out = '';
6855
6856
        // On recherche les groupes
6857
        $sql = "SELECT ug.rowid, ug.nom as name";
6858
        if (!empty(Globals::$conf->multicompany->enabled) && Globals::$conf->entity == 1 && $user->admin && !$user->entity) {
6859
            $sql .= ", e.label";
6860
        }
6861
        $sql .= " FROM " . MAIN_DB_PREFIX . "usergroup as ug ";
6862
        if (!empty(Globals::$conf->multicompany->enabled) && Globals::$conf->entity == 1 && $user->admin && !$user->entity) {
6863
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entity as e ON e.rowid=ug.entity";
6864
            if ($force_entity)
6865
                $sql .= " WHERE ug.entity IN (0," . $force_entity . ")";
6866
            else
6867
                $sql .= " WHERE ug.entity IS NOT NULL";
6868
        }
6869
        else {
6870
            $sql .= " WHERE ug.entity IN (0," . Globals::$conf->entity . ")";
6871
        }
6872
        if (is_array($exclude) && $excludeGroups)
6873
            $sql .= " AND ug.rowid NOT IN ('" . $excludeGroups . "')";
6874
        if (is_array($include) && $includeGroups)
6875
            $sql .= " AND ug.rowid IN ('" . $includeGroups . "')";
6876
        $sql .= " ORDER BY ug.nom ASC";
6877
6878
        dol_syslog(get_class($this) . "::select_dolgroups", LOG_DEBUG);
6879
        $resql = $this->db->query($sql);
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\Form. Did you maybe forget to declare it?
Loading history...
6880
        if ($resql) {
6881
            // Enhance with select2
6882
            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
6883
            $out .= ajax_combobox($htmlname);
6884
6885
            $out .= '<select class="flat minwidth200" id="' . $htmlname . '" name="' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple' : '') . ' ' . ($disabled ? ' disabled' : '') . '>';
6886
6887
            $num = $this->db->num_rows($resql);
6888
            $i = 0;
6889
            if ($num) {
6890
                if ($show_empty && !$multiple)
6891
                    $out .= '<option value="-1"' . (in_array(-1, $selected) ? ' selected' : '') . '>&nbsp;</option>' . "\n";
6892
6893
                while ($i < $num) {
6894
                    $obj = $this->db->fetch_object($resql);
6895
                    $disableline = 0;
6896
                    if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly))
6897
                        $disableline = 1;
6898
6899
                    $out .= '<option value="' . $obj->rowid . '"';
6900
                    if ($disableline)
6901
                        $out .= ' disabled';
6902
                    if ((is_object($selected[0]) && $selected[0]->id == $obj->rowid) || (!is_object($selected[0]) && in_array($obj->rowid, $selected) )) {
6903
                        $out .= ' selected';
6904
                    }
6905
                    $out .= '>';
6906
6907
                    $out .= $obj->name;
6908
                    if (!empty(Globals::$conf->multicompany->enabled) && empty(Globals::$conf->global->MULTICOMPANY_TRANSVERSE_MODE) && Globals::$conf->entity == 1) {
6909
                        $out .= " (" . $obj->label . ")";
6910
                    }
6911
6912
                    $out .= '</option>';
6913
                    $i++;
6914
                }
6915
            } else {
6916
                if ($show_empty)
6917
                    $out .= '<option value="-1"' . (in_array(-1, $selected) ? ' selected' : '') . '></option>' . "\n";
6918
                $out .= '<option value="" disabled>' . $langs->trans("NoUserGroupDefined") . '</option>';
6919
            }
6920
            $out .= '</select>';
6921
        }
6922
        else {
6923
            DolUtils::dol_print_error($this->db);
6924
        }
6925
6926
        return $out;
6927
    }
6928
6929
    /**
6930
     * 	Return HTML to show the search and clear seach button
6931
     *
6932
     *  @return	string
6933
     */
6934
    function showFilterButtons()
6935
    {
6936
        global $conf, $langs;
6937
6938
        $out = '<div class="nowrap">';
6939
        $out .= '<input type="image" class="liste_titre" name="button_search" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" value="' . DolUtils::dol_escape_htmltag($langs->trans("Search")) . '" title="' . DolUtils::dol_escape_htmltag($langs->trans("Search")) . '">';
6940
        $out .= '<input type="image" class="liste_titre" name="button_removefilter" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" value="' . DolUtils::dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . DolUtils::dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
6941
        $out .= '</div>';
6942
6943
        return $out;
6944
    }
6945
6946
    /**
6947
     * 	Return HTML to show the search and clear seach button
6948
     *
6949
     *  @param  string  $cssclass                  CSS class
6950
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6951
     *  @return	string
6952
     */
6953
    function showCheckAddButtons($cssclass = 'checkforaction', $calljsfunction = 0)
6954
    {
6955
        global $conf, $langs;
6956
6957
        $out = '';
6958
        if (!empty(Globals::$conf->use_javascript_ajax))
6959
            $out .= '<div class="inline-block checkallactions"><input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions"></div>';
6960
        $out .= '<script type="text/javascript">
6961
            $(document).ready(function() {
6962
            	$("#checkallactions").click(function() {
6963
                    if($(this).is(\':checked\')){
6964
                        console.log("We check all");
6965
                		$(".' . $cssclass . '").prop(\'checked\', true).trigger(\'change\');
6966
                    }
6967
                    else
6968
                    {
6969
                        console.log("We uncheck all");
6970
                		$(".' . $cssclass . '").prop(\'checked\', false).trigger(\'change\');
6971
                    }' . "\n";
6972
        if ($calljsfunction)
6973
            $out .= 'if (typeof initCheckForSelect == \'function\') { initCheckForSelect(0); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
6974
        $out .= '         });
6975
6976
        	$(".checkforselect").change(function() {
6977
				$(this).closest("tr").toggleClass("highlight", this.checked);
6978
			});
6979
6980
 	});
6981
    </script>';
6982
6983
        return $out;
6984
    }
6985
6986
    /**
6987
     * 	Return HTML to show the search and clear seach button
6988
     *
6989
     *  @param	int  	$addcheckuncheckall        Add the check all/uncheck all checkbox (use javascript) and code to manage this
6990
     *  @param  string  $cssclass                  CSS class
6991
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6992
     *  @return	string
6993
     */
6994
    function showFilterAndCheckAddButtons($addcheckuncheckall = 0, $cssclass = 'checkforaction', $calljsfunction = 0)
6995
    {
6996
        $out .= $this->showFilterButtons();
6997
        if ($addcheckuncheckall) {
6998
            $out .= $this->showCheckAddButtons($cssclass, $calljsfunction);
6999
        }
7000
        return $out;
7001
    }
7002
7003
    /**
7004
     * Return HTML to show the select of expense categories
7005
     *
7006
     * @param	string	$selected              preselected category
7007
     * @param	string	$htmlname              name of HTML select list
7008
     * @param	integer	$useempty              1=Add empty line
7009
     * @param	array	$excludeid             id to exclude
7010
     * @param	string	$target                htmlname of target select to bind event
7011
     * @param	int		$default_selected      default category to select if fk_c_type_fees change = EX_KME
7012
     * @param	array	$params                param to give
7013
     * @return	string
7014
     */
7015
    function selectExpenseCategories($selected = '', $htmlname = 'fk_c_exp_tax_cat', $useempty = 0, $excludeid = array(), $target = '', $default_selected = 0, $params = array())
7016
    {
7017
        global $db, $conf, $langs, $user;
7018
7019
        $sql = 'SELECT rowid, label FROM ' . MAIN_DB_PREFIX . 'c_exp_tax_cat WHERE active = 1';
7020
        $sql .= ' AND entity IN (0,' . getEntity('exp_tax_cat') . ')';
7021
        if (!empty($excludeid))
7022
            $sql .= ' AND rowid NOT IN (' . implode(',', $excludeid) . ')';
7023
        $sql .= ' ORDER BY label';
7024
7025
        $resql = $db->query($sql);
7026
        if ($resql) {
7027
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7028
            if ($useempty)
7029
                $out .= '<option value="0">&nbsp;</option>';
7030
7031
            while ($obj = $db->fetch_object($resql)) {
7032
                $out .= '<option ' . ($selected == $obj->rowid ? 'selected="selected"' : '') . ' value="' . $obj->rowid . '">' . $langs->trans($obj->label) . '</option>';
7033
            }
7034
            $out .= '</select>';
7035
            if (!empty($htmlname) && $user->admin)
7036
                $out .= ' ' . info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
7037
7038
            if (!empty($target)) {
7039
                $sql = "SELECT c.id FROM " . MAIN_DB_PREFIX . "c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1";
7040
                $resql = $db->query($sql);
7041
                if ($resql) {
7042
                    if ($db->num_rows($resql) > 0) {
7043
                        $obj = $db->fetch_object($resql);
7044
                        $out .= '<script type="text/javascript">
7045
							$(function() {
7046
								$("select[name=' . $target . ']").on("change", function() {
7047
									var current_val = $(this).val();
7048
									if (current_val == ' . $obj->id . ') {';
7049
                        if (!empty($default_selected) || !empty($selected))
7050
                            $out .= '$("select[name=' . $htmlname . ']").val("' . ($default_selected > 0 ? $default_selected : $selected) . '");';
7051
7052
                        $out .= '
7053
										$("select[name=' . $htmlname . ']").change();
7054
									}
7055
								});
7056
7057
								$("select[name=' . $htmlname . ']").change(function() {
7058
7059
									if ($("select[name=' . $target . ']").val() == ' . $obj->id . ') {
7060
										// get price of kilometer to fill the unit price
7061
										var data = ' . json_encode($params) . ';
7062
										data.fk_c_exp_tax_cat = $(this).val();
7063
7064
										$.ajax({
7065
											method: "POST",
7066
											dataType: "json",
7067
											data: data,
7068
											url: "' . (DOL_URL_ROOT . '/expensereport/ajax/ajaxik.php') . '",
7069
										}).done(function( data, textStatus, jqXHR ) {
7070
											console.log(data);
7071
											if (typeof data.up != "undefined") {
7072
												$("input[name=value_unit]").val(data.up);
7073
												$("select[name=' . $htmlname . ']").attr("title", data.title);
7074
											} else {
7075
												$("input[name=value_unit]").val("");
7076
												$("select[name=' . $htmlname . ']").attr("title", "");
7077
											}
7078
										});
7079
									}
7080
								});
7081
							});
7082
						</script>';
7083
                    }
7084
                }
7085
            }
7086
        }
7087
        else {
7088
            DolUtils::dol_print_error($db);
7089
        }
7090
7091
        return $out;
7092
    }
7093
7094
    /**
7095
     * Return HTML to show the select ranges of expense range
7096
     *
7097
     * @param	string	$selected    preselected category
7098
     * @param	string	$htmlname    name of HTML select list
7099
     * @param	integer	$useempty    1=Add empty line
7100
     * @return	string
7101
     */
7102
    function selectExpenseRanges($selected = '', $htmlname = 'fk_range', $useempty = 0)
7103
    {
7104
        global $db, $conf, $langs;
7105
7106
        $sql = 'SELECT rowid, range_ik FROM ' . MAIN_DB_PREFIX . 'c_exp_tax_range';
7107
        $sql .= ' WHERE entity = ' . Globals::$conf->entity . ' AND active = 1';
7108
7109
        $resql = $db->query($sql);
7110
        if ($resql) {
7111
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7112
            if ($useempty)
7113
                $out .= '<option value="0"></option>';
7114
7115
            while ($obj = $db->fetch_object($resql)) {
7116
                $out .= '<option ' . ($selected == $obj->rowid ? 'selected="selected"' : '') . ' value="' . $obj->rowid . '">' . price($obj->range_ik, 0, $langs, 1, 0) . '</option>';
7117
            }
7118
            $out .= '</select>';
7119
        } else {
7120
            DolUtils::dol_print_error($db);
7121
        }
7122
7123
        return $out;
7124
    }
7125
7126
    /**
7127
     * Return HTML to show a select of expense
7128
     *
7129
     * @param	string	$selected    preselected category
7130
     * @param	string	$htmlname    name of HTML select list
7131
     * @param	integer	$useempty    1=Add empty choice
7132
     * @param	integer	$allchoice   1=Add all choice
7133
     * @param	integer	$useid       0=use 'code' as key, 1=use 'id' as key
7134
     * @return	string
7135
     */
7136
    function selectExpense($selected = '', $htmlname = 'fk_c_type_fees', $useempty = 0, $allchoice = 1, $useid = 0)
7137
    {
7138
        global $db, $langs;
7139
7140
        $sql = 'SELECT id, code, label FROM ' . MAIN_DB_PREFIX . 'c_type_fees';
7141
        $sql .= ' WHERE active = 1';
7142
7143
        $resql = $db->query($sql);
7144
        if ($resql) {
7145
            $out = '<select id="select_' . $htmlname . '" name="' . $htmlname . '" class="' . $htmlname . ' flat minwidth75imp">';
7146
            if ($useempty)
7147
                $out .= '<option value="0"></option>';
7148
            if ($allchoice)
7149
                $out .= '<option value="-1">' . $langs->trans('AllExpenseReport') . '</option>';
7150
7151
            $field = 'code';
7152
            if ($useid)
7153
                $field = 'id';
7154
7155
            while ($obj = $db->fetch_object($resql)) {
7156
                $key = $langs->trans($obj->code);
7157
                $out .= '<option ' . ($selected == $obj->{$field} ? 'selected="selected"' : '') . ' value="' . $obj->{$field} . '">' . ($key != $obj->code ? $key : $obj->label) . '</option>';
7158
            }
7159
            $out .= '</select>';
7160
        } else {
7161
            DolUtils::dol_print_error($db);
7162
        }
7163
7164
        return $out;
7165
    }
7166
}
7167