1 | <?php |
||||||||
2 | /* <one line to give the program's name and a brief idea of what it does.> |
||||||||
3 | * Copyright (C) 2015 ATM Consulting <[email protected]> |
||||||||
4 | * |
||||||||
5 | * This program is free software: you can redistribute it and/or modify |
||||||||
6 | * it under the terms of the GNU General Public License as published by |
||||||||
7 | * the Free Software Foundation, either version 3 of the License, or |
||||||||
8 | * (at your option) any later version. |
||||||||
9 | * |
||||||||
10 | * This program is distributed in the hope that it will be useful, |
||||||||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||||
13 | * GNU General Public License for more details. |
||||||||
14 | * |
||||||||
15 | * You should have received a copy of the GNU General Public License |
||||||||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||||
17 | */ |
||||||||
18 | |||||||||
19 | /** |
||||||||
20 | * \file lib/importdevis.lib.php |
||||||||
21 | * \ingroup importdevis |
||||||||
22 | * \brief This file is an example module library |
||||||||
23 | * Put some comments here |
||||||||
24 | */ |
||||||||
25 | |||||||||
26 | function subtotalAdminPrepareHead() |
||||||||
27 | { |
||||||||
28 | global $langs, $conf; |
||||||||
29 | |||||||||
30 | $langs->load("subtotal@subtotal"); |
||||||||
31 | |||||||||
32 | $h = 0; |
||||||||
33 | $head = array(); |
||||||||
34 | |||||||||
35 | $head[$h][0] = dol_buildpath("/subtotal/admin/subtotal_setup.php", 1); |
||||||||
36 | $head[$h][1] = $langs->trans("Parameters"); |
||||||||
37 | $head[$h][2] = 'settings'; |
||||||||
38 | $h++; |
||||||||
39 | $head[$h][0] = dol_buildpath("/subtotal/admin/subtotal_about.php", 1); |
||||||||
40 | $head[$h][1] = $langs->trans("About"); |
||||||||
41 | $head[$h][2] = 'about'; |
||||||||
42 | $h++; |
||||||||
43 | |||||||||
44 | complete_head_from_modules($conf, $langs, $object, $head, $h, 'subtotal', $showLabel=false); |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() $showLabel = false of type false is incompatible with the type string expected by parameter $mode of complete_head_from_modules() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
45 | |||||||||
46 | return $head; |
||||||||
47 | } |
||||||||
48 | |||||||||
49 | function getHtmlSelectTitle(&$object, $showLabel=false) |
||||||||
50 | { |
||||||||
51 | global $langs; |
||||||||
52 | |||||||||
53 | require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php'; |
||||||||
54 | dol_include_once('/subtotal/class/subtotal.class.php'); |
||||||||
55 | $TTitle = TSubtotal::getAllTitleFromDocument($object); |
||||||||
56 | $html = ''; |
||||||||
57 | if ($showLabel) $html.= '<label for="under_title">'.$langs->trans('subtotalLabelForUnderTitle').'</label>'; |
||||||||
58 | $html.= '<select onChange="$(\'select[name=under_title]\').val(this.value);" name="under_title" class="under_title minwidth200"><option value="-1"></option>'; |
||||||||
59 | |||||||||
60 | $nbsp = ' '; |
||||||||
61 | foreach ($TTitle as &$line) |
||||||||
62 | { |
||||||||
63 | $str = str_repeat($nbsp, ($line->qty - 1) * 3); |
||||||||
64 | $html .= '<option value="'.$line->rang.'">'.$str.(!empty($line->label) ? $line->label : dol_trunc($line->desc, 30)).'</option>'; |
||||||||
65 | } |
||||||||
66 | |||||||||
67 | $html .= '</select>'; |
||||||||
68 | return $html; |
||||||||
69 | } |
||||||||
70 | |||||||||
71 | function getTFreeText() |
||||||||
72 | { |
||||||||
73 | global $db,$conf; |
||||||||
74 | |||||||||
75 | $TFreeText = array(); |
||||||||
76 | |||||||||
77 | $sql = 'SELECT rowid, label, content, active, entity FROM '.MAIN_DB_PREFIX.'c_subtotal_free_text WHERE active = 1 AND entity = '.$conf->entity.' ORDER BY label'; |
||||||||
78 | $resql = $db->query($sql); |
||||||||
79 | |||||||||
80 | if ($resql) |
||||||||
81 | { |
||||||||
82 | while ($row = $db->fetch_object($resql)) |
||||||||
83 | { |
||||||||
84 | $TFreeText[$row->rowid] = $row; |
||||||||
85 | } |
||||||||
86 | } |
||||||||
87 | |||||||||
88 | return $TFreeText; |
||||||||
89 | } |
||||||||
90 | |||||||||
91 | function getHtmlSelectFreeText($withEmpty=true) |
||||||||
92 | { |
||||||||
93 | global $langs; |
||||||||
94 | |||||||||
95 | $TFreeText = getTFreeText(); |
||||||||
96 | $html = '<label for="free_text">'.$langs->trans('subtotalLabelForFreeText').'</label>'; |
||||||||
97 | $html.= '<select onChange="getTFreeText($(this));" name="free_text" class="minwidth200">'; |
||||||||
98 | if ($withEmpty) $html.= '<option value=""></option>'; |
||||||||
99 | |||||||||
100 | $TFreeTextContents = array(); |
||||||||
101 | foreach ($TFreeText as $id => $tab) |
||||||||
102 | { |
||||||||
103 | $html.= '<option value="'.$id.'">'.$tab->label.'</option>'; |
||||||||
104 | $TFreeTextContents[$id] = $tab->content; |
||||||||
105 | } |
||||||||
106 | |||||||||
107 | $html .= '</select>'; |
||||||||
108 | |||||||||
109 | $html .= '<script type="text/javascript">'; |
||||||||
110 | $html .= 'function getTFreeText(select) {'; |
||||||||
111 | $html .= ' var TFreeText = '.json_encode($TFreeTextContents).';'; |
||||||||
112 | $html .= ' var id = select.val();'; |
||||||||
113 | $html .= ' if (id in TFreeText) {'; |
||||||||
114 | $html .= ' var content = TFreeText[id];'; |
||||||||
115 | $html .= ' if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && "sub-total-title" in CKEDITOR.instances) {'; |
||||||||
116 | $html .= ' var editor = CKEDITOR.instances["sub-total-title"];'; |
||||||||
117 | $html .= ' editor.setData(content);'; |
||||||||
118 | $html .= ' } else {'; |
||||||||
119 | $html .= ' $("#sub-total-title").val(content);'; |
||||||||
120 | $html .= ' }'; |
||||||||
121 | $html .= ' }'; |
||||||||
122 | $html .= '}'; |
||||||||
123 | $html .= '</script>'; |
||||||||
124 | |||||||||
125 | return $html; |
||||||||
126 | } |
||||||||
127 | |||||||||
128 | function _updateSubtotalLine(&$object, &$line) |
||||||||
129 | { |
||||||||
130 | global $conf; |
||||||||
131 | |||||||||
132 | $label = GETPOST('line-title', 'none'); |
||||||||
133 | $description = ($line->qty>90) ? '' : GETPOST('line-description', 'restricthtml'); |
||||||||
134 | $pagebreak = GETPOST('line-pagebreak', 'int'); |
||||||||
135 | $showTotalHT = GETPOST('line-showTotalHT', 'int'); |
||||||||
136 | $showReduc = GETPOST('line-showReduc', 'int'); |
||||||||
137 | |||||||||
138 | $level = GETPOST('subtotal_level', 'int'); |
||||||||
139 | if (!empty($level)) |
||||||||
140 | { |
||||||||
141 | if ($line->qty > 90) $line->qty = 100 - $level; // Si on edit une ligne sous-total |
||||||||
142 | else $line->qty = $level; |
||||||||
143 | } |
||||||||
144 | $line->array_options['options_show_total_ht'] = $showTotalHT; |
||||||||
145 | $line->array_options['options_show_reduc'] = $showReduc; |
||||||||
146 | |||||||||
147 | $res = TSubtotal::doUpdateLine($object, $line->id, $description, 0, $line->qty, 0, '', '', 0, 9, 0, 0, 'HT', $pagebreak, 0, 1, null, 0, $label, TSubtotal::$module_number, $line->array_options); |
||||||||
0 ignored issues
–
show
$pagebreak of type array|string is incompatible with the type integer expected by parameter $info_bits of TSubtotal::doUpdateLine() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$label can also be of type array and array and array ; however, parameter $label of TSubtotal::doUpdateLine() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$description can also be of type array and array and array ; however, parameter $desc of TSubtotal::doUpdateLine() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
148 | |||||||||
149 | $TKey = null; |
||||||||
150 | if ($line->element == 'propaldet') $TKey = explode(',', $conf->global->SUBTOTAL_LIST_OF_EXTRAFIELDS_PROPALDET); |
||||||||
151 | elseif ($line->element == 'commandedet') $TKey = explode(',', $conf->global->SUBTOTAL_LIST_OF_EXTRAFIELDS_COMMANDEDET); |
||||||||
152 | elseif ($line->element == 'facturedet') $TKey = explode(',', $conf->global->SUBTOTAL_LIST_OF_EXTRAFIELDS_FACTUREDET); |
||||||||
153 | // TODO ajouter la partie fournisseur |
||||||||
154 | |||||||||
155 | // TODO remove "true" |
||||||||
156 | if (!empty($TKey)) |
||||||||
157 | { |
||||||||
158 | $extrafields = new ExtraFields($object->db); |
||||||||
159 | $extrafields->fetch_name_optionals_label($line->element); |
||||||||
160 | $TPost = $extrafields->getOptionalsFromPost($line->element, '', 'subtotal_'); |
||||||||
161 | |||||||||
162 | $TLine = TSubtotal::getLinesFromTitleId($object, $line->id); |
||||||||
163 | foreach ($TLine as $object_line) |
||||||||
164 | { |
||||||||
165 | foreach ($TKey as $key) |
||||||||
166 | { |
||||||||
167 | // TODO remove "true" |
||||||||
168 | if (isset($TPost['subtotal_options_'.$key])) |
||||||||
169 | { |
||||||||
170 | $object_line->array_options['options_'.$key] = $TPost['subtotal_options_'.$key]; |
||||||||
171 | } |
||||||||
172 | } |
||||||||
173 | |||||||||
174 | $object_line->insertExtraFields(); |
||||||||
175 | } |
||||||||
176 | } |
||||||||
177 | |||||||||
178 | |||||||||
179 | |||||||||
180 | return $res; |
||||||||
181 | } |
||||||||
182 | |||||||||
183 | function _updateSubtotalBloc($object, $line) |
||||||||
184 | { |
||||||||
185 | global $conf,$langs; |
||||||||
186 | |||||||||
187 | $subtotal_tva_tx = $subtotal_tva_tx_init = GETPOST('subtotal_tva_tx', 'int'); |
||||||||
188 | $subtotal_progress = $subtotal_progress_init = GETPOST('subtotal_progress', 'int'); |
||||||||
189 | $array_options = $line->array_options; |
||||||||
190 | $showBlockExtrafields = GETPOST('showBlockExtrafields', 'none'); |
||||||||
191 | |||||||||
192 | if ($subtotal_tva_tx != '' || $subtotal_progress != '' || (!empty($showBlockExtrafields) && !empty($array_options))) |
||||||||
193 | { |
||||||||
194 | $error_progress = $nb_progress_update = $nb_progress_not_updated = 0; |
||||||||
0 ignored issues
–
show
|
|||||||||
195 | $TLine = TSubtotal::getLinesFromTitleId($object, $line->id); |
||||||||
196 | foreach ($TLine as &$line) |
||||||||
0 ignored issues
–
show
|
|||||||||
197 | { |
||||||||
198 | if (!TSubtotal::isModSubtotalLine($line)) |
||||||||
199 | { |
||||||||
200 | $subtotal_tva_tx = $subtotal_tva_tx_init; // ré-init car la variable peut évoluer |
||||||||
201 | |||||||||
202 | if (!empty($showBlockExtrafields)) $line->array_options = $array_options; |
||||||||
203 | if ($subtotal_tva_tx == '') $subtotal_tva_tx = $line->tva_tx; |
||||||||
204 | if ($object->element == 'facture' && !empty($conf->global->INVOICE_USE_SITUATION) && $object->type == Facture::TYPE_SITUATION) |
||||||||
205 | { |
||||||||
206 | $subtotal_progress = $subtotal_progress_init; |
||||||||
207 | if ($subtotal_progress == '') $subtotal_progress = $line->situation_percent; |
||||||||
208 | else |
||||||||
209 | { |
||||||||
210 | $prev_percent = $line->get_prev_progress($object->id); |
||||||||
211 | if ($subtotal_progress < $prev_percent) |
||||||||
212 | { |
||||||||
213 | $nb_progress_not_updated++; |
||||||||
214 | $subtotal_progress = $line->situation_percent; |
||||||||
215 | } |
||||||||
216 | } |
||||||||
217 | } |
||||||||
218 | |||||||||
219 | $res = TSubtotal::doUpdateLine($object, $line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $subtotal_tva_tx, $line->product_type, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $subtotal_progress, $line->fk_unit); |
||||||||
220 | |||||||||
221 | if ($res > 0) $success_updated_line++; |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
222 | else $error_updated_line++; |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
223 | } |
||||||||
224 | } |
||||||||
225 | |||||||||
226 | if ($nb_progress_not_updated > 0) setEventMessage($langs->trans('subtotal_nb_progress_not_updated', $nb_progress_not_updated), 'warnings'); |
||||||||
227 | |||||||||
228 | if ($success_updated_line > 0) setEventMessage($langs->trans('subtotal_success_updated_line', $success_updated_line)); |
||||||||
229 | if ($error_updated_line > 0) |
||||||||
230 | { |
||||||||
231 | setEventMessage($langs->trans('subtotal_error_updated_line', $error_updated_line), 'errors'); |
||||||||
232 | return -$error_updated_line; |
||||||||
233 | } |
||||||||
234 | |||||||||
235 | return $success_updated_line; |
||||||||
236 | } |
||||||||
237 | |||||||||
238 | return 0; |
||||||||
239 | } |
||||||||
240 | |||||||||
241 | function _createExtraComprisNonCompris() |
||||||||
242 | { |
||||||||
243 | global $db; |
||||||||
244 | |||||||||
245 | dol_include_once('/core/class/extrafields.class.php'); |
||||||||
246 | |||||||||
247 | $extra = new ExtraFields($db); // propaldet, commandedet, facturedet |
||||||||
248 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'propaldet', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
249 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'commandedet', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
250 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'facturedet', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
251 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'supplier_proposaldet', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
252 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'commande_fournisseurdet', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
253 | $extra->addExtraField('subtotal_nc', 'Non compris', 'varchar', 0, 255, 'facture_fourn_det', 0, 0, '', unserialize('a:1:{s:7:"options";a:1:{s:0:"";N;}}'), 0, '', 0, 1); |
||||||||
254 | } |
||||||||
255 | |||||||||
256 | |||||||||
257 | |||||||||
258 | /** |
||||||||
259 | * Maj du bloc pour forcer le total_tva et total_ht à 0 et recalculer le total du document |
||||||||
260 | * |
||||||||
261 | * @param $lineid = title lineid |
||||||||
0 ignored issues
–
show
|
|||||||||
262 | * @param $subtotal_nc 0 = "Compris" prise en compte des totaux des lignes; 1 = "Non compris" non prise en compte des totaux du bloc; null = update de toutes les lignes |
||||||||
263 | */ |
||||||||
264 | function _updateLineNC($element, $elementid, $lineid, $subtotal_nc=null, $notrigger = 0) |
||||||||
265 | { |
||||||||
266 | global $db,$langs,$tmp_object_nc; |
||||||||
267 | |||||||||
268 | $error = 0; |
||||||||
269 | if (empty($element)) $error++; |
||||||||
270 | |||||||||
271 | if (!$error) |
||||||||
272 | { |
||||||||
273 | if (!empty($tmp_object_nc) && $tmp_object_nc->element == $element && $tmp_object_nc->id == $elementid) |
||||||||
274 | { |
||||||||
275 | $object = $tmp_object_nc; |
||||||||
276 | } |
||||||||
277 | else |
||||||||
278 | { |
||||||||
279 | $classname = ucfirst($element); |
||||||||
280 | |||||||||
281 | switch ($element) { |
||||||||
282 | case 'supplier_proposal': |
||||||||
283 | $classname = 'SupplierProposal'; |
||||||||
284 | break; |
||||||||
285 | |||||||||
286 | case 'order_supplier': |
||||||||
287 | $classname = 'CommandeFournisseur'; |
||||||||
288 | break; |
||||||||
289 | |||||||||
290 | case 'invoice_supplier': |
||||||||
291 | $classname = 'FactureFournisseur'; |
||||||||
292 | break; |
||||||||
293 | } |
||||||||
294 | |||||||||
295 | $object = new $classname($db); // Propal | Commande | Facture |
||||||||
296 | $res = $object->fetch($elementid); |
||||||||
297 | if ($res < 0) $error++; |
||||||||
298 | else $tmp_object_nc = $object; |
||||||||
299 | } |
||||||||
300 | } |
||||||||
301 | |||||||||
302 | if (!$error) |
||||||||
303 | { |
||||||||
304 | foreach ($object->lines as &$l) |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
305 | { |
||||||||
306 | if($l->id == $lineid) { |
||||||||
307 | $line = $l; |
||||||||
308 | break; |
||||||||
309 | } |
||||||||
310 | } |
||||||||
311 | |||||||||
312 | if (!empty($line)) |
||||||||
313 | { |
||||||||
314 | $db->begin(); |
||||||||
315 | |||||||||
316 | if(TSubtotal::isModSubtotalLine($line)) |
||||||||
317 | { |
||||||||
318 | if(TSubtotal::isTitle($line)) { |
||||||||
319 | // Update le contenu du titre (ainsi que le titre lui même) |
||||||||
320 | $TTitleBlock = TSubtotal::getLinesFromTitleId($object, $lineid, true); |
||||||||
321 | foreach($TTitleBlock as &$line_block) |
||||||||
322 | { |
||||||||
323 | $res = doUpdate($object, $line_block, $subtotal_nc, $notrigger); |
||||||||
0 ignored issues
–
show
|
|||||||||
324 | } |
||||||||
325 | } |
||||||||
326 | } |
||||||||
327 | else |
||||||||
328 | { |
||||||||
329 | $res = doUpdate($object, $line, $subtotal_nc, $notrigger); |
||||||||
330 | } |
||||||||
331 | |||||||||
332 | $res = $object->update_price(1); |
||||||||
333 | if ($res <= 0) $error++; |
||||||||
334 | |||||||||
335 | if (!$error) |
||||||||
336 | { |
||||||||
337 | setEventMessage($langs->trans('subtotal_update_nc_success')); |
||||||||
338 | $db->commit(); |
||||||||
339 | } |
||||||||
340 | else |
||||||||
341 | { |
||||||||
342 | setEventMessage($langs->trans('subtotal_update_nc_error'), 'errors'); |
||||||||
343 | $db->rollback(); |
||||||||
344 | } |
||||||||
345 | } |
||||||||
346 | } |
||||||||
347 | } |
||||||||
348 | |||||||||
349 | function doUpdate(&$object, &$line, $subtotal_nc, $notrigger = 0) |
||||||||
350 | { |
||||||||
351 | global $user, $conf; |
||||||||
352 | |||||||||
353 | if (TSubtotal::isFreeText($line) || TSubtotal::isSubtotal($line)) return 1; |
||||||||
354 | // Update extrafield et total |
||||||||
355 | if(! empty($subtotal_nc)) { |
||||||||
356 | $line->total_ht = $line->total_tva = $line->total_ttc = $line->total_localtax1 = $line->total_localtax2 = |
||||||||
357 | $line->multicurrency_total_ht = $line->multicurrency_total_tva = $line->multicurrency_total_ttc = 0; |
||||||||
358 | if(!empty($conf->global->SUBTOTAL_NONCOMPRIS_UPDATE_PA_HT)) $line->pa_ht = '0'; |
||||||||
359 | |||||||||
360 | $line->array_options['options_subtotal_nc'] = 1; |
||||||||
361 | |||||||||
362 | if ($line->element == 'propaldet') $res = $line->update($notrigger); |
||||||||
363 | else $res = $line->update($user, $notrigger); |
||||||||
364 | } |
||||||||
365 | else { |
||||||||
366 | if(in_array($object->element, array('invoice_supplier', 'order_supplier', 'supplier_proposal'))) { |
||||||||
367 | if(empty($line->label)) $line->label = $line->description; // supplier lines don't have the field label |
||||||||
368 | |||||||||
369 | require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); |
||||||||
370 | $extrafields=new ExtraFields($object->db); |
||||||||
371 | $extralabels=$extrafields->fetch_name_optionals_label($object->table_element_line,true); |
||||||||
372 | $line->fetch_optionals($line->id,$extralabels); |
||||||||
373 | } |
||||||||
374 | $line->array_options['options_subtotal_nc'] = 0; |
||||||||
375 | if($object->element == 'order_supplier') $line->update($user); |
||||||||
376 | $res = TSubtotal::doUpdateLine($object, $line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->product_type, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $notrigger); |
||||||||
377 | } |
||||||||
378 | |||||||||
379 | return $res; |
||||||||
380 | } |
||||||||
381 | |||||||||
382 | function _updateLine($element, $elementid, $lineid) |
||||||||
383 | { |
||||||||
384 | _updateLineNC($element, $elementid, $lineid); |
||||||||
385 | } |
||||||||
386 |