Passed
Push — master ( 0f9140...c4489d )
by Alxarafe
22:27
created

Base/AlForm.php (64 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\AlDolUtils;
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 AlForm
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
0 ignored issues
show
The type Alixar\Base\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
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);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arraylist seems to be defined by a foreach iteration on line 240. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
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'));
0 ignored issues
show
The type Alixar\Base\DolEditor was not found. Did you mean DolEditor? If so, make sure to prefix the type with \.
Loading history...
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 .= AlDolUtils::dol_print_date($value, 'day');
277
                elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
278
                    $ret .= AlDolUtils::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 = AlDolUtils::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 : AlDolUtils::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 : AlDolUtils::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) {
0 ignored issues
show
The expression $arrayofaction of type integer is not traversable.
Loading history...
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="' . AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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
The type Alixar\Base\Societe was not found. Did you mean Societe? If so, make sure to prefix the type with \.
Loading history...
Bug Best Practice introduced by
The property db does not exist on Alixar\Base\AlForm. 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\AlForm. 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
            AlDolUtils::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\AlForm. 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);
0 ignored issues
show
The type Alixar\Base\Facture was not found. Did you mean Facture? If so, make sure to prefix the type with \.
Loading history...
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
            AlDolUtils::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\AlForm. 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)
0 ignored issues
show
Consider adding parentheses for clarity. Current Interpretation: ($showempty == 1 || $sho...num > 1) && ! $multiple, Probably Intended Meaning: $showempty == 1 || ($sho...num > 1 && ! $multiple)
Loading history...
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);
0 ignored issues
show
The type Alixar\Base\Contact was not found. Did you mean Contact? If so, make sure to prefix the type with \.
Loading history...
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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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="' . AlDolUtils::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\AlForm. Did you maybe forget to declare it?
Loading history...
The type Alixar\Base\Product was not found. Did you mean Product? If so, make sure to prefix the type with \.
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;
0 ignored issues
show
The type Alixar\Base\Entrepot was not found. Did you mean Entrepot? If so, make sure to prefix the type with \.
Loading history...
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\AlForm. 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);
0 ignored issues
show
The type Alixar\Base\PriceParser was not found. Did you mean PriceParser? If so, make sure to prefix the type with \.
Loading history...
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
            AlDolUtils::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 != '')
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $filterkey seems to never exist and therefore empty should always be true.
Loading history...
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\AlForm. 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
                AlDolUtils::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\AlForm. 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\AlForm. 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);
0 ignored issues
show
The type Alixar\Base\ProductFournisseur was not found. Did you mean ProductFournisseur? If so, make sure to prefix the type with \.
Loading history...
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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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\AlForm. 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\AlForm. 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\AlForm. 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
            AlDolUtils::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\AlForm. Did you maybe forget to declare it?
Loading history...
The type Alixar\Base\Account was not found. Did you mean Account? If so, make sure to prefix the type with \.
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) {
0 ignored issues
show
The type Alixar\Base\Categorie was not found. Did you mean Categorie? If so, make sure to prefix the type with \.
Loading history...
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\AlForm. 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
                AlDolUtils::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="' . AlDolUtils::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="' . AlDolUtils::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\AlForm. Did you maybe forget to declare it?
Loading history...
The type Alixar\Base\FormProjets was not found. Did you mean FormProjets? If so, make sure to prefix the type with \.
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);
0 ignored issues
show
The type Alixar\Base\Project was not found. Did you mean Project? If so, make sure to prefix the type with \.
Loading history...
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 .= AlDolUtils::dol_print_date($selected, 'dayhour');
4189
            else
4190
                $ret .= AlDolUtils::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\AlForm. 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="' . AlDolUtils::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\AlForm. 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\AlForm. 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\AlForm. 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 . "'";
0 ignored issues
show
The property country_code does not exist on string.
Loading history...
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\AlForm. 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.
0 ignored issues
show
The type Alixar\Base\datetime was not found. Did you mean datetime? If so, make sure to prefix the type with \.
Loading history...
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 = AlDolUtils::dol_print_date($set_time, "%Y");
4956
            $smonth = AlDolUtils::dol_print_date($set_time, "%m");
4957
            $sday = AlDolUtils::dol_print_date($set_time, "%d");
4958
            if ($orig_set_time != '') {
4959
                $shour = AlDolUtils::dol_print_date($set_time, "%H");
4960
                $smin = AlDolUtils::dol_print_date($set_time, "%M");
4961
                $ssec = AlDolUtils::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 = AlDolUtils::dol_print_date($set_time, $langs->trans("FormatDateShortInput"));  // FormatDateShortInput for AlDolUtils::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 AlDolUtils::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 AlDolUtils::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 .= AlDolUtils::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="' . AlDolUtils::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(\'' . AlDolUtils::dol_print_date(dol_now(), 'day') . '\');';
5168
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . AlDolUtils::dol_print_date(dol_now(), '%d') . '\');';
5169
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . AlDolUtils::dol_print_date(dol_now(), '%m') . '\');';
5170
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . AlDolUtils::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(\'' . AlDolUtils::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(\'' . AlDolUtils::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(\'' . AlDolUtils::dol_print_date(dol_now(), 'day') . '\');';
5215
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . AlDolUtils::dol_print_date(dol_now(), '%d') . '\');';
5216
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . AlDolUtils::dol_print_date(dol_now(), '%m') . '\');';
5217
            $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . AlDolUtils::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(\'' . AlDolUtils::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(\'' . AlDolUtils::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(\'' . AlDolUtils::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\AlForm. 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\AlForm. 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
            AlDolUtils::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 = AlDolUtils::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 = AlDolUtils::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="' . AlDolUtils::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) {
0 ignored issues
show
The expression $array of type string is not traversable.
Loading history...
5776
            $o = new stdClass();
0 ignored issues
show
The type Alixar\Base\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
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 . ' -->
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tmpplugin seems to be never defined.
Loading history...
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 . '">' . AlDolUtils::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');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arrayselected seems to be defined by a foreach iteration on line 6079. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
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
0 ignored issues
show
The type Alixar\Base\CommonObject was not found. Did you mean CommonObject? If so, make sure to prefix the type with \.
Loading history...
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
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $action seems to be never defined.
Loading history...
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\AlForm. 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
                    AlDolUtils::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\AlForm. 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
            AlDolUtils::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>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $langs seems to be never defined.
Loading history...
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
            AlDolUtils::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\AlForm. 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
            AlDolUtils::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="' . AlDolUtils::dol_escape_htmltag($langs->trans("Search")) . '" title="' . AlDolUtils::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="' . AlDolUtils::dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . AlDolUtils::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();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $out seems to be never defined.
Loading history...
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
            AlDolUtils::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
            AlDolUtils::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
            AlDolUtils::dol_print_error($db);
7162
        }
7163
7164
        return $out;
7165
    }
7166
}
7167