dolibarr 21.0.0-beta
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@capnetworks.com>
5 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
6 * Copyright (C) 2023-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
7 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
9 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
31// Load Dolibarr environment
32require '../main.inc.php';
33require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php';
34require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
35require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
36require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
41
50$langs->loadLangs(array("sendings", "receptions", "deliveries", 'companies', 'bills', 'orders'));
51
52$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'shipmentlist'; // To manage different context of search
53
54$socid = GETPOSTINT('socid');
55
56$action = GETPOST('action', 'alpha');
57$massaction = GETPOST('massaction', 'alpha');
58$toselect = GETPOST('toselect', 'array');
59$optioncss = GETPOST('optioncss', 'alpha');
60$mode = GETPOST('mode', 'alpha');
61
62
63$search_ref_rcp = GETPOST("search_ref_rcp");
64$search_ref_liv = GETPOST('search_ref_liv');
65$search_ref_supplier = GETPOST('search_ref_supplier');
66$search_company = GETPOST("search_company");
67$search_town = GETPOST('search_town', 'alpha');
68$search_zip = GETPOST('search_zip', 'alpha');
69$search_state = GETPOST("search_state");
70$search_country = GETPOST("search_country", 'aZ09');
71$search_type_thirdparty = GETPOST("search_type_thirdparty", 'intcomma');
72$search_date_delivery_startday = GETPOSTINT('search_date_delivery_startday');
73$search_date_delivery_startmonth = GETPOSTINT('search_date_delivery_startmonth');
74$search_date_delivery_startyear = GETPOSTINT('search_date_delivery_startyear');
75$search_date_delivery_endday = GETPOSTINT('search_date_delivery_endday');
76$search_date_delivery_endmonth = GETPOSTINT('search_date_delivery_endmonth');
77$search_date_delivery_endyear = GETPOSTINT('search_date_delivery_endyear');
78$search_date_delivery_start = dol_mktime(0, 0, 0, $search_date_delivery_startmonth, $search_date_delivery_startday, $search_date_delivery_startyear); // Use tzserver
79$search_date_delivery_end = dol_mktime(23, 59, 59, $search_date_delivery_endmonth, $search_date_delivery_endday, $search_date_delivery_endyear);
80$search_date_create_startday = GETPOSTINT('search_date_create_startday');
81$search_date_create_startmonth = GETPOSTINT('search_date_create_startmonth');
82$search_date_create_startyear = GETPOSTINT('search_date_create_startyear');
83$search_date_create_endday = GETPOSTINT('search_date_create_endday');
84$search_date_create_endmonth = GETPOSTINT('search_date_create_endmonth');
85$search_date_create_endyear = GETPOSTINT('search_date_create_endyear');
86$search_date_create_start = dol_mktime(0, 0, 0, $search_date_create_startmonth, $search_date_create_startday, $search_date_create_startyear); // Use tzserver
87$search_date_create_end = dol_mktime(23, 59, 59, $search_date_create_endmonth, $search_date_create_endday, $search_date_create_endyear);
88$search_billed = GETPOST("search_billed", 'intcomma');
89$search_status = GETPOST('search_status', 'intcomma');
90$search_all = GETPOST('search_all', 'alphanohtml');
91
92$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
93$sortfield = GETPOST('sortfield', 'aZ09comma');
94$sortorder = GETPOST('sortorder', 'aZ09comma');
95$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
96if (!$sortfield) {
97 $sortfield = "e.ref";
98}
99if (!$sortorder) {
100 $sortorder = "DESC";
101}
102if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
103 // If $page is not defined, or '' or -1 or if we click on clear filters
104 $page = 0;
105}
106$offset = $limit * $page;
107$pageprev = $page - 1;
108$pagenext = $page + 1;
109
110$diroutputmassaction = $conf->reception->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id;
111$object = new Reception($db);
112
113// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
114$hookmanager->initHooks(array('receptionlist'));
115$extrafields = new ExtraFields($db);
116
117// Fetch optionals attributes and labels
118$extrafields->fetch_name_optionals_label($object->table_element);
119$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
120
121// List of fields to search into when doing a "search in all"
122$fieldstosearchall = array(
123 'e.ref' => "Ref",
124 'e.ref_supplier' => "RefSupplier",
125 's.nom' => "ThirdParty",
126 'e.note_public' => 'NotePublic',
127);
128if (empty($user->socid)) {
129 $fieldstosearchall["e.note_private"] = "NotePrivate";
130}
131
132$checkedtypetiers = 0;
133$arrayfields = array(
134 'e.ref' => array('label' => $langs->trans("Ref"), 'checked' => 1),
135 'e.ref_supplier' => array('label' => $langs->trans("RefSupplier"), 'checked' => 1),
136 's.nom' => array('label' => $langs->trans("ThirdParty"), 'checked' => 1),
137 's.town' => array('label' => $langs->trans("Town"), 'checked' => 1),
138 's.zip' => array('label' => $langs->trans("Zip"), 'checked' => 1),
139 'state.nom' => array('label' => $langs->trans("StateShort"), 'checked' => 0),
140 'country.code_iso' => array('label' => $langs->trans("Country"), 'checked' => 0),
141 'typent.code' => array('label' => $langs->trans("ThirdPartyType"), 'checked' => $checkedtypetiers),
142 'e.date_delivery' => array('label' => $langs->trans("DateDeliveryPlanned"), 'checked' => 1),
143 'e.datec' => array('label' => $langs->trans("DateCreation"), 'checked' => 0, 'position' => 500),
144 'e.tms' => array('label' => $langs->trans("DateModificationShort"), 'checked' => 0, 'position' => 500),
145 'e.fk_statut' => array('label' => $langs->trans("Status"), 'checked' => 1, 'position' => 1000),
146 'e.billed' => array('label' => $langs->trans("Billed"), 'checked' => 1, 'position' => 1000, 'enabled' => 'getDolGlobalString("WORKFLOW_BILL_ON_RECEPTION") !== "0"')
147);
148
149// Extra fields
150include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
151
152$object->fields = dol_sort_array($object->fields, 'position');
153$arrayfields = dol_sort_array($arrayfields, 'position');
154'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
155
156$error = 0;
157
158// Security check
159$receptionid = GETPOSTINT('id');
160if ($user->socid) {
161 $socid = $user->socid;
162}
163$result = restrictedArea($user, 'reception', $receptionid, '');
164
165
166/*
167 * Actions
168 */
169
170if (GETPOST('cancel', 'alpha')) {
171 $action = 'list';
172 $massaction = '';
173}
174if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_createbills') {
175 $massaction = '';
176}
177
178$parameters = array('socid' => $socid, 'arrayfields' => &$arrayfields);
179$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
180if ($reshook < 0) {
181 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
182}
183
184include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
185
186// Purge search criteria
187if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
188 $search_ref_supplier = '';
189 $search_ref_rcp = '';
190 $search_ref_liv = '';
191 $search_company = '';
192 $search_town = '';
193 $search_zip = "";
194 $search_state = "";
195 $search_country = '';
196 $search_type_thirdparty = '';
197 $search_date_delivery_startday = '';
198 $search_date_delivery_startmonth = '';
199 $search_date_delivery_startyear = '';
200 $search_date_delivery_endday = '';
201 $search_date_delivery_endmonth = '';
202 $search_date_delivery_endyear = '';
203 $search_date_delivery_start = '';
204 $search_date_delivery_end = '';
205 $search_date_create_startday = '';
206 $search_date_create_startmonth = '';
207 $search_date_create_startyear = '';
208 $search_date_create_endday = '';
209 $search_date_create_endmonth = '';
210 $search_date_create_endyear = '';
211 $search_date_create_start = '';
212 $search_date_create_end = '';
213 $search_billed = '';
214 $search_status = '';
215 $toselect = array();
216 $search_array_options = array();
217}
218
219if (empty($reshook)) {
220 // Mass actions
221 $objectclass = 'Reception';
222 $objectlabel = 'Receptions';
223 $permissiontoread = $user->hasRight('reception', 'lire');
224 $permissiontoadd = $user->hasRight('reception', 'creer');
225 $permissiontodelete = $user->hasRight('reception', 'supprimer');
226 $uploaddir = $conf->reception->multidir_output[$conf->entity];
227 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
228
229 if ($massaction == 'confirm_createbills' && ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"))) {
230 $receptions = GETPOST('toselect', 'array');
231 $createbills_onebythird = GETPOSTINT('createbills_onebythird');
232 $validate_invoices = GETPOSTINT('validate_invoices');
233
234 $errors = array();
235
236 $TFact = array();
237 $TFactThird = array();
238 '@phan-var FactureFournisseur[] $TFactThird';
239 $TFactThirdNbLines = array();
240
241 $nb_bills_created = 0;
242 $lastid = 0;
243 $lastref = '';
244
245 $db->begin();
246
247 //sort ids to keep order if one bill per third
248 sort($receptions);
249 foreach ($receptions as $id_reception) {
250 $rcp = new Reception($db);
251 // We not allow invoice reception that are in draft status
252 if ($rcp->fetch($id_reception) <= 0 || $rcp->statut == $rcp::STATUS_DRAFT) {
253 $errors[] = $langs->trans('StatusOfRefMustBe', $rcp->ref, $langs->transnoentities("StatusReceptionValidatedShort"));
254 $error++;
255 continue;
256 }
257
258 $objecttmp = new FactureFournisseur($db);
259 if (!empty($createbills_onebythird) && !empty($TFactThird[$rcp->socid])) {
260 // If option "one bill per third" is set, and an invoice for this thirdparty was already created, we reuse it.
261 $objecttmp = $TFactThird[$rcp->socid];
262
263 // Add all links of this new reception to the existing invoice
264 $objecttmp->fetchObjectLinked();
265 $rcp->fetchObjectLinked();
266 if (!empty($rcp->linkedObjectsIds['order_supplier']) && is_array($rcp->linkedObjectsIds['order_supplier'])) {
267 foreach ($rcp->linkedObjectsIds['order_supplier'] as $key => $value) {
268 if (empty($objecttmp->linkedObjectsIds['order_supplier']) || !in_array($value, $objecttmp->linkedObjectsIds['order_supplier'])) { //Don't try to link if already linked
269 $objecttmp->add_object_linked('order_supplier', $value); // add supplier order linked object
270 }
271 }
272 }
273 } else {
274 $cond_reglement_id = 0;
275 $mode_reglement_id = 0;
276 $fk_account = 0;
277 $transport_mode_id = 0;
278 if (!empty($rcp->cond_reglement_id)) {
279 $cond_reglement_id = $rcp->cond_reglement_id;
280 }
281 if (!empty($rcp->mode_reglement_id)) {
282 $mode_reglement_id = $rcp->mode_reglement_id;
283 }
284 if (!empty($rcp->fk_account)) {
285 $fk_account = $rcp->fk_account;
286 }
287 if (!empty($rcp->transport_mode_id)) {
288 $transport_mode_id = $rcp->transport_mode_id;
289 }
290
291 if (empty($cond_reglement_id)
292 || empty($mode_reglement_id)
293 || empty($fk_account)
294 || empty($transport_mode_id)
295 ) {
296 if (!isset($rcp->supplier_order)) {
297 $rcp->fetch_origin();
298 }
299
300 // try to get from source of reception (supplier order)
301 if (!empty($rcp->origin_object)) {
302 $supplierOrder = $rcp->origin_object;
303 if (empty($cond_reglement_id) && !empty($supplierOrder->cond_reglement_id)) {
304 $cond_reglement_id = $supplierOrder->cond_reglement_id;
305 }
306 if (empty($mode_reglement_id) && !empty($supplierOrder->mode_reglement_id)) {
307 $mode_reglement_id = $supplierOrder->mode_reglement_id;
308 }
309 if (empty($fk_account) && !empty($supplierOrder->fk_account)) {
310 $fk_account = $supplierOrder->fk_account;
311 }
312 if (empty($transport_mode_id) && !empty($supplierOrder->transport_mode_id)) {
313 $transport_mode_id = $supplierOrder->transport_mode_id;
314 }
315 }
316
317 $soc = null;
318 // try get from third party of reception
319 if (!empty($rcp->thirdparty)) {
320 $soc = $rcp->thirdparty;
321 if (empty($cond_reglement_id) && !empty($soc->cond_reglement_supplier_id)) {
322 $cond_reglement_id = $soc->cond_reglement_supplier_id;
323 }
324 if (empty($mode_reglement_id) && !empty($soc->mode_reglement_supplier_id)) {
325 $mode_reglement_id = $soc->mode_reglement_supplier_id;
326 }
327 if (empty($fk_account) && !empty($soc->fk_account)) {
328 $fk_account = $soc->fk_account;
329 }
330 if (empty($transport_mode_id) && !empty($soc->transport_mode_id)) {
331 $transport_mode_id = $soc->transport_mode_id;
332 }
333 }
334 }
335
336 // If we want one invoice per reception or if there is no first invoice yet for this thirdparty.
337 $objecttmp->socid = $rcp->socid;
338 $objecttmp->type = $objecttmp::TYPE_STANDARD;
339 $objecttmp->cond_reglement_id = $cond_reglement_id;
340 $objecttmp->mode_reglement_id = $mode_reglement_id;
341 $objecttmp->fk_account = $fk_account;
342 $objecttmp->transport_mode_id = $transport_mode_id;
343
344 // if the VAT reverse-charge is activated by default in supplier card to resume the information
345 if (is_object($soc)) {
346 $objecttmp->vat_reverse_charge = $soc->vat_reverse_charge;
347 }
348
349 $objecttmp->fk_project = $rcp->fk_project;
350 //$objecttmp->multicurrency_code = $rcp->multicurrency_code;
351 if (empty($createbills_onebythird)) {
352 $objecttmp->ref_supplier = $rcp->ref;
353 } else {
354 // Set a unique value for the invoice for the n reception
355 $objecttmp->ref_supplier = $langs->trans("Reception").' '.dol_print_date(dol_now(), 'dayhourlog').'-'.$rcp->socid;
356 }
357
358 $datefacture = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
359 if (empty($datefacture)) {
360 $datefacture = dol_now();
361 }
362
363 $objecttmp->date = $datefacture;
364 $objecttmp->origin = 'reception';
365 $objecttmp->origin_id = $id_reception;
366
367 // Auto calculation of date due if not filled by user
368 if (empty($objecttmp->date_echeance)) {
369 $objecttmp->date_echeance = $objecttmp->calculate_date_lim_reglement();
370 }
371
372 $objecttmp->array_options = $rcp->array_options; // Copy extrafields
373
374 // Set $objecttmp->linked_objects with all links order_supplier existing on reception, so same links will be added to the generated supplier invoice
375 $rcp->fetchObjectLinked();
376 if (count($rcp->linkedObjectsIds['order_supplier']) > 0) {
377 foreach ($rcp->linkedObjectsIds['order_supplier'] as $key => $value) {
378 $objecttmp->linked_objects['order_supplier'] = $value;
379 }
380 }
381
382 $res = $objecttmp->create($user); // This should create the supplier invoice + links into $objecttmp->linked_objects + add a link to ->origin_id
383
384 //var_dump($objecttmp->error);exit;
385 if ($res > 0) {
386 $nb_bills_created++;
387 $lastref = $objecttmp->ref;
388 $lastid = $objecttmp->id;
389
390 $TFactThird[$rcp->socid] = $objecttmp;
391 $TFactThirdNbLines[$rcp->socid] = 0; //init nblines to have lines ordered by expedition and rang
392 } else {
393 $langs->load("errors");
394 $errors[] = $rcp->ref.' : '.$langs->trans($objecttmp->error);
395 $error++;
396 }
397 }
398
399 if ($objecttmp->id > 0) {
400 $res = $objecttmp->add_object_linked($objecttmp->origin, $id_reception);
401
402 if ($res == 0) {
403 $errors[] = $objecttmp->error;
404 $error++;
405 }
406
407 if (!$error) {
408 $lines = $rcp->lines;
409 if (empty($lines) && method_exists($rcp, 'fetch_lines')) {
410 $rcp->fetch_lines();
411 $lines = $rcp->lines;
412 }
413
414 $fk_parent_line = 0;
415 $num = count($lines);
416
417 for ($i = 0; $i < $num; $i++) {
418 $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle);
419 // If we build one invoice for several reception, we must put the ref of reception on the invoice line
420 if (!empty($createbills_onebythird)) {
421 $desc = dol_concatdesc($desc, $langs->trans("Reception").' '.$rcp->ref);
422 $desc .= (!empty($rcp->date_reception) ? ' - '.dol_print_date($rcp->date_reception, 'day') : '');
423 }
424
425 if ($lines[$i]->subprice < 0) {
426 // Negative line, we create a discount line
427 $discount = new DiscountAbsolute($db);
428 $discount->fk_soc = $objecttmp->socid;
429 $discount->socid = $objecttmp->socid;
430 $discount->amount_ht = abs($lines[$i]->total_ht);
431 $discount->amount_tva = abs($lines[$i]->total_tva);
432 $discount->amount_ttc = abs($lines[$i]->total_ttc);
433 $discount->tva_tx = $lines[$i]->tva_tx;
434 $discount->fk_user = $user->id;
435 $discount->description = $desc;
436 $discountid = $discount->create($user);
437 if ($discountid > 0) {
438 $result = $objecttmp->insert_discount($discountid);
439 //$result=$discount->link_to_invoice($lineid,$id);
440 } else {
441 setEventMessages($discount->error, $discount->errors, 'errors');
442 $error++;
443 break;
444 }
445 } else {
446 // Positive line
447 $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
448 // Date start
449 $date_start = false;
450 if ($lines[$i]->date_debut_prevue) {
451 $date_start = $lines[$i]->date_debut_prevue;
452 }
453 if ($lines[$i]->date_debut_reel) {
454 $date_start = $lines[$i]->date_debut_reel;
455 }
456 if ($lines[$i]->date_start) {
457 $date_start = $lines[$i]->date_start;
458 }
459 //Date end
460 $date_end = false;
461 if ($lines[$i]->date_fin_prevue) {
462 $date_end = $lines[$i]->date_fin_prevue;
463 }
464 if ($lines[$i]->date_fin_reel) {
465 $date_end = $lines[$i]->date_fin_reel;
466 }
467 if ($lines[$i]->date_end) {
468 $date_end = $lines[$i]->date_end;
469 }
470 // Reset fk_parent_line for no child products and special product
471 if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
472 $fk_parent_line = 0;
473 }
474
475 // Extrafields
476 if (method_exists($lines[$i], 'fetch_optionals')) {
477 $lines[$i]->fetch_optionals();
478 $array_options = $lines[$i]->array_options;
479 }
480
481 $objecttmp->context['createfromclone'] = 'createfromclone';
482
483 $rang = $i;
484 //there may already be rows from previous receptions
485 if (!empty($createbills_onebythird)) {
486 $rang = $TFactThirdNbLines[$rcp->socid];
487 }
488
489 $result = $objecttmp->addline(
490 $desc,
491 $lines[$i]->subprice,
492 $lines[$i]->tva_tx,
493 $lines[$i]->localtax1_tx,
494 $lines[$i]->localtax2_tx,
495 $lines[$i]->qty,
496 $lines[$i]->fk_product,
497 $lines[$i]->remise_percent,
498 $date_start,
499 $date_end,
500 0,
501 $lines[$i]->info_bits,
502 'HT',
503 $product_type,
504 $rang,
505 false,
506 array(),
507 null,
508 $lines[$i]->rowid,
509 0,
510 $lines[$i]->ref_supplier
511 );
512
513 $rcp->add_object_linked('facture_fourn_det', $result);
514
515 if ($result > 0) {
516 $lineid = $result;
517 if (!empty($createbills_onebythird)) { //increment rang to keep order
518 $TFactThirdNbLines[$rcp->socid]++;
519 }
520 } else {
521 $lineid = 0;
522 $error++;
523 break;
524 }
525 // Defined the new fk_parent_line
526 if ($result > 0 && $lines[$i]->product_type == 9) {
527 $fk_parent_line = $result;
528 }
529 }
530 }
531 }
532 }
533
534 //$rcp->classifyBilled($user); // Disabled. This behavior must be set or not using the workflow module.
535
536 if (!empty($createbills_onebythird) && empty($TFactThird[$rcp->socid])) {
537 $TFactThird[$rcp->socid] = $objecttmp;
538 } else {
539 $TFact[$objecttmp->id] = $objecttmp;
540 }
541 }
542
543 // Build doc with all invoices
544 $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird;
545 $toselect = array();
546
547 if (!$error && $validate_invoices) {
548 $massaction = $action = 'builddoc';
549 foreach ($TAllFact as &$objecttmp) {
550 $result = $objecttmp->validate($user);
551 if ($result <= 0) {
552 $error++;
553 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
554 break;
555 }
556
557 $id = $objecttmp->id; // For builddoc action
558 $lastref = $objecttmp->ref; // generated ref
559 $object = $objecttmp;
560
561 // Fac builddoc
562 $donotredirect = 1;
563 $upload_dir = $conf->fournisseur->facture->dir_output;
564 $permissiontoadd = ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer'));
565
566 // Call action to build doc
567 $savobject = $object;
568 $object = $objecttmp;
569 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
570 $object = $savobject;
571 }
572
573 $massaction = $action = 'confirm_createbills';
574 }
575
576 if (!$error) {
577 $db->commit();
578
579 if ($nb_bills_created == 1) {
580 $texttoshow = $langs->trans('BillXCreated', '{s1}');
581 $texttoshow = str_replace('{s1}', '<a href="'.DOL_URL_ROOT.'/fourn/facture/card.php?id='.urlencode((string) ($lastid)).'">'.$lastref.'</a>', $texttoshow);
582 setEventMessages($texttoshow, null, 'mesgs');
583 } else {
584 setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs');
585 }
586 } else {
587 $db->rollback();
588
589 $action = 'create';
590 $_GET["origin"] = $_POST["origin"]; // Keep this ?
591 $_GET["originid"] = $_POST["originid"]; // Keep this ?
592 setEventMessages($object->error, $errors, 'errors');
593 $error++;
594 }
595 }
596}
597
598
599/*
600 * View
601 */
602
603$now = dol_now();
604
605$form = new Form($db);
606$companystatic = new Societe($db);
607$reception = new Reception($db);
608$formcompany = new FormCompany($db);
609$formfile = new FormFile($db);
610
611$title = $langs->trans('Receptions');
612$helpurl = 'EN:Module_Receptions|FR:Module_Receptions|ES:M&oacute;dulo_Receptiones';
613llxHeader('', $title, $helpurl, '', 0, 0, '', '', '', 'bodyforlist mod-reception page-list');
614
615$sql = "SELECT e.rowid, e.ref, e.ref_supplier, e.date_reception as date_reception, e.date_delivery as delivery_date, l.date_delivery as date_reception2, e.fk_statut as status, e.billed,";
616$sql .= " s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client,";
617$sql .= " typent.code as typent_code,";
618$sql .= " state.code_departement as state_code, state.nom as state_name,";
619$sql .= " e.date_creation as date_creation, e.tms as date_modification";
620// Add fields from extrafields
621if (!empty($extrafields->attributes[$object->table_element]['label'])) {
622 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
623 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
624 }
625}
626// Add fields from hooks
627$parameters = array();
628$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
629$sql .= $hookmanager->resPrint;
630
631$sqlfields = $sql; // $sql fields to remove for count total
632
633$sql .= " FROM ".MAIN_DB_PREFIX."reception as e";
634if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
635 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (e.rowid = ef.fk_object)";
636}
637$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc";
638$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)";
639$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)";
640$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)";
641$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as ee ON e.rowid = ee.fk_source AND ee.sourcetype = 'reception' AND ee.targettype = 'delivery'";
642$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."delivery as l ON l.rowid = ee.fk_target";
643// Add table from hooks
644$parameters = array();
645$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
646$sql .= $hookmanager->resPrint;
647$sql .= " WHERE e.entity IN (".getEntity('reception').")";
648if ($socid) {
649 $sql .= " AND e.fk_soc = ".((int) $socid);
650}
651if ($search_status != '' && $search_status >= 0) {
652 $sql .= " AND e.fk_statut = ".((int) $search_status);
653}
654if ($search_billed != '' && $search_billed >= 0) {
655 $sql .= ' AND e.billed = '.((int) $search_billed);
656}
657if ($search_town) {
658 $sql .= natural_search('s.town', $search_town);
659}
660if ($search_zip) {
661 $sql .= natural_search("s.zip", $search_zip);
662}
663if ($search_state) {
664 $sql .= natural_search("state.nom", $search_state);
665}
666if ($search_country) {
667 $sql .= " AND s.fk_pays IN (".$db->sanitize($search_country).')';
668}
669if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) {
670 $sql .= " AND s.fk_typent IN (".$db->sanitize($search_type_thirdparty).')';
671}
672if ($search_date_delivery_start) {
673 $sql .= " AND e.date_delivery >= '".$db->idate($search_date_delivery_start)."'";
674}
675if ($search_date_delivery_end) {
676 $sql .= " AND e.date_delivery <= '".$db->idate($search_date_delivery_end)."'";
677}
678if ($search_date_create_start) {
679 $sql .= " AND e.date_creation >= '".$db->idate($search_date_create_start)."'";
680}
681if ($search_date_create_end) {
682 $sql .= " AND e.date_creation <= '".$db->idate($search_date_create_end)."'";
683}
684if ($search_ref_rcp) {
685 $sql .= natural_search('e.ref', $search_ref_rcp);
686}
687if ($search_ref_liv) {
688 $sql .= natural_search('l.ref', $search_ref_liv);
689}
690if ($search_company) {
691 $sql .= natural_search('s.nom', $search_company);
692}
693if ($search_ref_supplier) {
694 $sql .= natural_search('e.ref_supplier', $search_ref_supplier);
695}
696if ($search_all) {
697 $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
698}
699// Search on sale representative
700/*
701if ($search_sale && $search_sale != '-1') {
702 if ($search_sale == -2) {
703 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc)";
704 } elseif ($search_sale > 0) {
705 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = c.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
706 }
707}
708*/
709// Add where from extra fields
710include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
711// Add where from hooks
712$parameters = array();
713$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
714$sql .= $hookmanager->resPrint;
715
716// Add HAVING from hooks
717$parameters = array();
718$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook
719$sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
720
721$nbtotalofrecords = '';
722if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
723 /* The fast and low memory method to get and count full list converts the sql into a sql count */
724 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
725 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
726 $resql = $db->query($sqlforcount);
727 if ($resql) {
728 $objforcount = $db->fetch_object($resql);
729 $nbtotalofrecords = $objforcount->nbtotalofrecords;
730 } else {
731 dol_print_error($db);
732 }
733
734 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
735 $page = 0;
736 $offset = 0;
737 }
738 $db->free($resql);
739}
740
741// Complete request and execute it with limit
742$sql .= $db->order($sortfield, $sortorder);
743if ($limit) {
744 $sql .= $db->plimit($limit + 1, $offset);
745}
746
747//print $sql;
748$resql = $db->query($sql);
749if (!$resql) {
750 dol_print_error($db);
751 exit;
752}
753
754$num = $db->num_rows($resql);
755
756$reception = new Reception($db);
757
758$arrayofselected = is_array($toselect) ? $toselect : array();
759
760$param = '';
761if (!empty($mode)) {
762 $param .= '&mode='.urlencode($mode);
763}
764if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
765 $param .= '&contextpage='.urlencode($contextpage);
766}
767if ($limit > 0 && $limit != $conf->liste_limit) {
768 $param .= '&limit='.((int) $limit);
769}
770if ($search_all) {
771 $param .= "&search_all=".urlencode($search_all);
772}
773if ($search_ref_rcp) {
774 $param .= "&search_ref_rcp=".urlencode($search_ref_rcp);
775}
776if ($search_ref_liv) {
777 $param .= "&search_ref_liv=".urlencode($search_ref_liv);
778}
779if ($search_company) {
780 $param .= "&search_company=".urlencode($search_company);
781}
782if ($optioncss != '') {
783 $param .= '&optioncss='.urlencode($optioncss);
784}
785if ($search_billed != '' && $search_billed >= 0) {
786 $param .= "&search_billed=".urlencode((string) ($search_billed));
787}
788if ($search_town) {
789 $param .= "&search_town=".urlencode($search_town);
790}
791if ($search_zip) {
792 $param .= "&search_zip=".urlencode($search_zip);
793}
794if ($search_state) {
795 $param .= "&search_state=".urlencode($search_state);
796}
797if ($search_status != '') {
798 $param .= "&search_status=".urlencode($search_status);
799}
800if ($search_country) {
801 $param .= "&search_country=".urlencode((string) ($search_country));
802}
803if ($search_type_thirdparty) {
804 $param .= "&search_type_thirdparty=".urlencode((string) ($search_type_thirdparty));
805}
806if ($search_date_delivery_startday) {
807 $param .= '&search_date_delivery_startday='.urlencode((string) ($search_date_delivery_startday));
808}
809if ($search_date_delivery_startmonth) {
810 $param .= '&search_date_delivery_startmonth='.urlencode((string) ($search_date_delivery_startmonth));
811}
812if ($search_date_delivery_startyear) {
813 $param .= '&search_date_delivery_startyear='.urlencode((string) ($search_date_delivery_startyear));
814}
815if ($search_date_delivery_endday) {
816 $param .= '&search_date_delivery_endday='.urlencode((string) ($search_date_delivery_endday));
817}
818if ($search_date_delivery_endmonth) {
819 $param .= '&search_date_delivery_endmonth='.urlencode((string) ($search_date_delivery_endmonth));
820}
821if ($search_date_delivery_endyear) {
822 $param .= '&search_date_delivery_endyear='.urlencode((string) ($search_date_delivery_endyear));
823}
824if ($search_date_create_startday) {
825 $param .= '&search_date_create_startday='.urlencode((string) ($search_date_create_startday));
826}
827if ($search_date_create_startmonth) {
828 $param .= '&search_date_create_startmonth='.urlencode((string) ($search_date_create_startmonth));
829}
830if ($search_date_create_startyear) {
831 $param .= '&search_date_create_startyear='.urlencode((string) ($search_date_create_startyear));
832}
833if ($search_date_create_endday) {
834 $param .= '&search_date_create_endday='.urlencode((string) ($search_date_create_endday));
835}
836if ($search_date_create_endmonth) {
837 $param .= '&search_date_create_endmonth='.urlencode((string) ($search_date_create_endmonth));
838}
839if ($search_date_create_endyear) {
840 $param .= '&search_date_create_endyear='.urlencode((string) ($search_date_create_endyear));
841}
842if ($search_ref_supplier) {
843 $param .= "&search_ref_supplier=".urlencode($search_ref_supplier);
844}
845// Add $param from extra fields
846if ($search_array_options) {
847 foreach ($search_array_options as $key => $val) {
848 $crit = $val;
849 $tmpkey = preg_replace('/search_options_/', '', $key);
850 if (is_array($val) && array_key_exists('start', $val) && array_key_exists('end', $val)) {
851 // date range from list filters is stored as array('start' => <timestamp>, 'end' => <timestamp>)
852 // start date
853 $param .= '&search_options_'.$tmpkey.'_startyear='.dol_print_date($val['start'], '%Y');
854 $param .= '&search_options_'.$tmpkey.'_startmonth='.dol_print_date($val['start'], '%m');
855 $param .= '&search_options_'.$tmpkey.'_startday='.dol_print_date($val['start'], '%d');
856 $param .= '&search_options_'.$tmpkey.'_starthour='.dol_print_date($val['start'], '%H');
857 $param .= '&search_options_'.$tmpkey.'_startmin='.dol_print_date($val['start'], '%M');
858 // end date
859 $param .= '&search_options_'.$tmpkey.'_endyear='.dol_print_date($val['end'], '%Y');
860 $param .= '&search_options_'.$tmpkey.'_endmonth='.dol_print_date($val['end'], '%m');
861 $param .= '&search_options_'.$tmpkey.'_endday='.dol_print_date($val['end'], '%d');
862 $param .= '&search_options_'.$tmpkey.'_endhour='.dol_print_date($val['end'], '%H');
863 $param .= '&search_options_'.$tmpkey.'_endmin='.dol_print_date($val['end'], '%M');
864 $val = '';
865 }
866 if ($val != '') {
867 $param .= '&search_options_'.$tmpkey.'='.urlencode($val);
868 }
869 }
870}
871
872
873$arrayofmassactions = array(
874 'builddoc' => img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
875 // 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
876);
877
878if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer')) {
879 $arrayofmassactions['createbills'] = $langs->trans("CreateInvoiceForThisReceptions");
880}
881if (in_array($massaction, array('presend', 'createbills'))) {
882 $arrayofmassactions = array();
883}
884$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
885
886// Currently: a sending can't create from sending list
887// $url = DOL_URL_ROOT.'/expedition/card.php?action=create';
888// if (!empty($socid)) $url .= '&socid='.$socid;
889// $newcardbutton = dolGetButtonTitle($langs->trans('NewSending'), '', 'fa fa-plus-circle', $url, '', $user->rights->expedition->creer);
890$newcardbutton = '';
891$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
892$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
893$newcardbutton .= dolGetButtonTitleSeparator();
894$newcardbutton .= dolGetButtonTitle($langs->trans('NewReception'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/reception/card.php?action=create2', '', $user->hasRight('reception', 'creer'));
895
896$i = 0;
897print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'."\n";
898if ($optioncss != '') {
899 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
900}
901print '<input type="hidden" name="token" value="'.newToken().'">';
902print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
903print '<input type="hidden" name="action" value="list">';
904print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
905print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
906print '<input type="hidden" name="mode" value="'.$mode.'">';
907
908// @phan-suppress-next-line PhanPluginSuspiciousParamOrder
909print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'dollyrevert', 0, $newcardbutton, '', $limit, 0, 0, 1);
910
911if ($massaction == 'createbills') {
912 //var_dump($_REQUEST);
913 print '<input type="hidden" name="massaction" value="confirm_createbills">';
914
915 print '<table class="noborder centpercent">';
916 print '<tr>';
917 print '<td class="titlefieldmiddle">';
918 print $langs->trans('DateInvoice');
919 print '</td>';
920 print '<td>';
921 print $form->selectDate('', '', 0, 0, 0, '', 1, 1);
922 print '</td>';
923 print '</tr>';
924 print '<tr>';
925 print '<td>';
926 print $langs->trans('CreateOneBillByThird');
927 print '</td>';
928 print '<td>';
929 print $form->selectyesno('createbills_onebythird', '', 1);
930 print '</td>';
931 print '</tr>';
932 print '<tr>';
933 print '<td>';
934 print $langs->trans('ValidateInvoices');
935 print '</td>';
936 print '<td>';
937 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_BILL')) {
938 print $form->selectyesno('validate_invoices', 0, 1, 1);
939 print ' ('.$langs->trans("AutoValidationNotPossibleWhenStockIsDecreasedOnInvoiceValidation").')';
940 } else {
941 print $form->selectyesno('validate_invoices', 0, 1);
942 }
943 print '</td>';
944 print '</tr>';
945 print '</table>';
946
947 print '<br>';
948 print '<div class="center">';
949 print '<input type="submit" class="button" id="createbills" name="createbills" value="'.$langs->trans('CreateInvoiceForThisReceptions').'"> ';
950 print '<input type="submit" class="button button-cancel" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
951 print '</div>';
952 print '<br>';
953}
954
955if ($search_all) {
956 foreach ($fieldstosearchall as $key => $val) {
957 $fieldstosearchall[$key] = $langs->trans($val);
958 }
959 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>';
960}
961
962$moreforfilter = '';
963
964if (!empty($moreforfilter)) {
965 print '<div class="liste_titre liste_titre_bydiv centpercent">';
966 print $moreforfilter;
967 $parameters = array('type' => $type);
968 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
969 print $hookmanager->resPrint;
970 print '</div>';
971}
972
973$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
974$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN'));
975if ($massactionbutton) {
976 $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); // This also change content of $arrayfields
977}
978
979print '<div class="div-table-responsive">';
980print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
981
982// Fields title search
983// --------------------------------------------------------------------
984print '<tr class="liste_titre_filter">';
985// Action column
986if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
987 print '<td class="liste_titre center maxwidthsearch">';
988 $searchpicto = $form->showFilterButtons('left');
989 print $searchpicto;
990 print '</td>';
991}
992// Ref
993if (!empty($arrayfields['e.ref']['checked'])) {
994 print '<td class="liste_titre">';
995 print '<input class="flat" size="6" type="text" name="search_ref_rcp" value="'.$search_ref_rcp.'">';
996 print '</td>';
997}
998// Ref customer
999if (!empty($arrayfields['e.ref_supplier']['checked'])) {
1000 print '<td class="liste_titre">';
1001 print '<input class="flat" size="6" type="text" name="search_ref_supplier" value="'.$search_ref_supplier.'">';
1002 print '</td>';
1003}
1004// Thirdparty
1005if (!empty($arrayfields['s.nom']['checked'])) {
1006 print '<td class="liste_titre left">';
1007 print '<input class="flat" type="text" size="8" name="search_company" value="'.dol_escape_htmltag($search_company).'">';
1008 print '</td>';
1009}
1010// Town
1011if (!empty($arrayfields['s.town']['checked'])) {
1012 print '<td class="liste_titre"><input class="flat" type="text" size="6" name="search_town" value="'.$search_town.'"></td>';
1013}
1014// Zip
1015if (!empty($arrayfields['s.zip']['checked'])) {
1016 print '<td class="liste_titre"><input class="flat" type="text" size="6" name="search_zip" value="'.$search_zip.'"></td>';
1017}
1018// State
1019if (!empty($arrayfields['state.nom']['checked'])) {
1020 print '<td class="liste_titre">';
1021 print '<input class="flat" size="4" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">';
1022 print '</td>';
1023}
1024// Country
1025if (!empty($arrayfields['country.code_iso']['checked'])) {
1026 print '<td class="liste_titre center">';
1027 print $form->select_country($search_country, 'search_country', '', 0, 'minwidth100imp maxwidth100');
1028 print '</td>';
1029}
1030// Company type
1031if (!empty($arrayfields['typent.code']['checked'])) {
1032 print '<td class="liste_titre maxwidthonsmartphone center">';
1033 print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 1, 0, 0, '', 0, 0, 0, (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT), '', 1);
1034 print '</td>';
1035}
1036// Date delivery planned
1037if (!empty($arrayfields['e.date_delivery']['checked'])) {
1038 print '<td class="liste_titre center">';
1039 print '<div class="nowrapfordate">';
1040 print $form->selectDate($search_date_delivery_start ? $search_date_delivery_start : -1, 'search_date_delivery_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1041 print '</div>';
1042 print '<div class="nowrapfordate">';
1043 print $form->selectDate($search_date_delivery_end ? $search_date_delivery_end : -1, 'search_date_delivery_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1044 print '</div>';
1045 print '</td>';
1046}
1047if (!empty($arrayfields['l.ref']['checked'])) {
1048 // Delivery ref
1049 print '<td class="liste_titre">';
1050 print '<input class="flat" type="text" name="search_ref_liv" value="'.dol_escape_htmltag($search_ref_liv).'"';
1051 print '</td>';
1052}
1053if (!empty($arrayfields['l.date_delivery']['checked'])) {
1054 // Date received
1055 print '<td class="liste_titre center">&nbsp;</td>';
1056}
1057// Extra fields
1058include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1059
1060// Fields from hook
1061$parameters = array('arrayfields' => $arrayfields);
1062$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
1063print $hookmanager->resPrint;
1064// Date creation
1065if (!empty($arrayfields['e.datec']['checked'])) {
1066 print '<td class="liste_titre center">';
1067 print '<div class="nowrapfordate">';
1068 print $form->selectDate($search_date_create_start ? $search_date_create_start : -1, 'search_date_create_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1069 print '</div>';
1070 print '<div class="nowrapfordate">';
1071 print $form->selectDate($search_date_create_end ? $search_date_create_end : -1, 'search_date_create_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1072 print '</div>';
1073 print '</td>';
1074}
1075// Date modification
1076if (!empty($arrayfields['e.tms']['checked'])) {
1077 print '<td class="liste_titre">';
1078 print '</td>';
1079}
1080// Status
1081if (!empty($arrayfields['e.fk_statut']['checked'])) {
1082 print '<td class="liste_titre right parentonrightofpage">';
1083 print $form->selectarray('search_status', array('0' => $langs->trans('StatusReceptionDraftShort'), '1' => $langs->trans('StatusReceptionValidatedShort'), '2' => $langs->trans('StatusReceptionProcessedShort')), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'search_status width100 onrightofpage');
1084 print '</td>';
1085}
1086// Status billed
1087if (!empty($arrayfields['e.billed']['checked'])) {
1088 print '<td class="liste_titre maxwidthonsmartphone center">';
1089 print $form->selectyesno('search_billed', $search_billed, 1, 0, 1);
1090 print '</td>';
1091}
1092// Action column
1093if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1094 print '<td class="liste_titre middle">';
1095 $searchpicto = $form->showFilterButtons();
1096 print $searchpicto;
1097 print '</td>';
1098}
1099print '</tr>'."\n";
1100
1101$totalarray = array();
1102$totalarray['nbfield'] = 0;
1103
1104// Fields title label
1105// --------------------------------------------------------------------
1106print '<tr class="liste_titre">';
1107// Action column
1108if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1109 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1110 $totalarray['nbfield']++;
1111}
1112if (!empty($arrayfields['e.ref']['checked'])) {
1113 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1114 print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"], "e.ref", "", $param, '', $sortfield, $sortorder);
1115 $totalarray['nbfield']++;
1116}
1117if (!empty($arrayfields['e.ref_supplier']['checked'])) {
1118 print_liste_field_titre($arrayfields['e.ref_supplier']['label'], $_SERVER["PHP_SELF"], "e.ref_supplier", "", $param, '', $sortfield, $sortorder);
1119 $totalarray['nbfield']++;
1120}
1121if (!empty($arrayfields['s.nom']['checked'])) {
1122 print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder, 'left ');
1123 $totalarray['nbfield']++;
1124}
1125if (!empty($arrayfields['s.town']['checked'])) {
1126 print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder);
1127 $totalarray['nbfield']++;
1128}
1129if (!empty($arrayfields['s.zip']['checked'])) {
1130 print_liste_field_titre($arrayfields['s.zip']['label'], $_SERVER["PHP_SELF"], 's.zip', '', $param, '', $sortfield, $sortorder);
1131 $totalarray['nbfield']++;
1132}
1133if (!empty($arrayfields['state.nom']['checked'])) {
1134 print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder);
1135 $totalarray['nbfield']++;
1136}
1137if (!empty($arrayfields['country.code_iso']['checked'])) {
1138 print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, '', $sortfield, $sortorder, 'center ');
1139 $totalarray['nbfield']++;
1140}
1141if (!empty($arrayfields['typent.code']['checked'])) {
1142 print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, '', $sortfield, $sortorder, 'center ');
1143 $totalarray['nbfield']++;
1144}
1145if (!empty($arrayfields['e.date_delivery']['checked'])) {
1146 print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"], "e.date_delivery", "", $param, '', $sortfield, $sortorder, 'center ');
1147 $totalarray['nbfield']++;
1148}
1149if (!empty($arrayfields['l.ref']['checked'])) {
1150 print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"], "l.ref", "", $param, '', $sortfield, $sortorder);
1151 $totalarray['nbfield']++;
1152}
1153if (!empty($arrayfields['l.date_delivery']['checked'])) {
1154 print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"], "l.date_delivery", "", $param, '', $sortfield, $sortorder, 'center ');
1155 $totalarray['nbfield']++;
1156}
1157// Extra fields
1158include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1159// Hook fields
1160$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, '$totalarray' => &$totalarray);
1161$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
1162print $hookmanager->resPrint;
1163if (!empty($arrayfields['e.datec']['checked'])) {
1164 print_liste_field_titre($arrayfields['e.datec']['label'], $_SERVER["PHP_SELF"], "e.date_creation", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1165 $totalarray['nbfield']++;
1166}
1167if (!empty($arrayfields['e.tms']['checked'])) {
1168 print_liste_field_titre($arrayfields['e.tms']['label'], $_SERVER["PHP_SELF"], "e.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1169 $totalarray['nbfield']++;
1170}
1171if (!empty($arrayfields['e.fk_statut']['checked'])) {
1172 print_liste_field_titre($arrayfields['e.fk_statut']['label'], $_SERVER["PHP_SELF"], "e.fk_statut", "", $param, '', $sortfield, $sortorder, 'right ');
1173 $totalarray['nbfield']++;
1174}
1175if (!empty($arrayfields['e.billed']['checked'])) {
1176 print_liste_field_titre($arrayfields['e.billed']['label'], $_SERVER["PHP_SELF"], "e.billed", "", $param, '', $sortfield, $sortorder, 'center ');
1177 $totalarray['nbfield']++;
1178}
1179// Action column
1180if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1181 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1182 $totalarray['nbfield']++;
1183}
1184print "</tr>\n";
1185
1186
1187// Loop on record
1188// --------------------------------------------------------------------
1189$i = 0;
1190$savnbfield = $totalarray['nbfield'];
1191$totalarray = array();
1192$totalarray['nbfield'] = 0;
1193$imaxinloop = ($limit ? min($num, $limit) : $num);
1194while ($i < $imaxinloop) {
1195 $obj = $db->fetch_object($resql);
1196 if (empty($obj)) {
1197 break; // Should not happen
1198 }
1199
1200 $reception->id = $obj->rowid;
1201 $reception->ref = $obj->ref;
1202 //$reception->ref_supplier = $obj->ref_supplier;
1203 $reception->statut = $obj->status;
1204 $reception->status = $obj->status;
1205 $reception->socid = $obj->socid;
1206 $reception->billed = $obj->billed;
1207
1208 $reception->fetch_thirdparty();
1209
1210 $object = $reception;
1211
1212 $companystatic->id = $obj->socid;
1213 $companystatic->ref = $obj->name;
1214 $companystatic->name = $obj->name;
1215
1216 if ($mode == 'kanban') {
1217 if ($i == 0) {
1218 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
1219 print '<div class="box-flex-container kanban">';
1220 }
1221 $object->date_delivery = $obj->delivery_date;
1222 $object->town = $obj->town;
1223
1224 // Output Kanban
1225 $selected = -1;
1226 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1227 $selected = 0;
1228 if (in_array($object->id, $arrayofselected)) {
1229 $selected = 1;
1230 }
1231 }
1232 print $object->getKanbanView('', array('thirdparty' => $companystatic->getNomUrl(1), 'selected' => $selected));
1233 if ($i == min($num, $limit) - 1) {
1234 print '</div>';
1235 print '</td></tr>';
1236 }
1237 } else {
1238 print '<tr class="oddeven">';
1239
1240 // Action column
1241 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1242 print '<td class="nowrap center">';
1243 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1244 $selected = 0;
1245 if (in_array($obj->rowid, $arrayofselected)) {
1246 $selected = 1;
1247 }
1248 print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
1249 }
1250 print '</td>';
1251 }
1252 // Ref
1253 if (!empty($arrayfields['e.ref']['checked'])) {
1254 print '<td class="nowraponall">';
1255 print $reception->getNomUrl(1);
1256 $filename = dol_sanitizeFileName($reception->ref);
1257 $filedir = $conf->reception->dir_output.'/'.dol_sanitizeFileName($reception->ref);
1258 $urlsource = $_SERVER['PHP_SELF'].'?id='.$reception->id;
1259 print $formfile->getDocumentsLink($reception->element, $filename, $filedir);
1260 print "</td>\n";
1261
1262 if (!$i) {
1263 $totalarray['nbfield']++;
1264 }
1265 }
1266
1267 // Ref supplier
1268 if (!empty($arrayfields['e.ref_supplier']['checked'])) {
1269 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($obj->ref_supplier).'">';
1270 print dol_escape_htmltag($obj->ref_supplier);
1271 print "</td>\n";
1272 if (!$i) {
1273 $totalarray['nbfield']++;
1274 }
1275 }
1276
1277 // Third party
1278 if (!empty($arrayfields['s.nom']['checked'])) {
1279 print '<td class="tdoverflowmax150">';
1280 print $companystatic->getNomUrl(1);
1281 print '</td>';
1282 if (!$i) {
1283 $totalarray['nbfield']++;
1284 }
1285 }
1286 // Town
1287 if (!empty($arrayfields['s.town']['checked'])) {
1288 print '<td class="nocellnopadd tdoverflowmax200" title="'.dol_escape_htmltag($obj->town).'">';
1289 print dol_escape_htmltag($obj->town);
1290 print '</td>';
1291 if (!$i) {
1292 $totalarray['nbfield']++;
1293 }
1294 }
1295 // Zip
1296 if (!empty($arrayfields['s.zip']['checked'])) {
1297 print '<td class="nocellnopadd center"">';
1298 print dol_escape_htmltag($obj->zip);
1299 print '</td>';
1300 if (!$i) {
1301 $totalarray['nbfield']++;
1302 }
1303 }
1304 // State
1305 if (!empty($arrayfields['state.nom']['checked'])) {
1306 print "<td>".dol_escape_htmltag($obj->state_name)."</td>\n";
1307 if (!$i) {
1308 $totalarray['nbfield']++;
1309 }
1310 }
1311 // Country
1312 if (!empty($arrayfields['country.code_iso']['checked'])) {
1313 print '<td class="center">';
1314 $tmparray = getCountry($obj->fk_pays, 'all');
1315 print dol_escape_htmltag($tmparray['label']);
1316 print '</td>';
1317 if (!$i) {
1318 $totalarray['nbfield']++;
1319 }
1320 }
1321 // Type ent
1322 if (!empty($arrayfields['typent.code']['checked'])) {
1323 print '<td class="center">';
1324 if (!isset($typenArray) || empty($typenArray)) {
1325 $typenArray = $formcompany->typent_array(1);
1326 }
1327 if (isset($typenArray[$obj->typent_code])) {
1328 print $typenArray[$obj->typent_code];
1329 }
1330 print '</td>';
1331 if (!$i) {
1332 $totalarray['nbfield']++;
1333 }
1334 }
1335
1336 // Date delivery planned
1337 if (!empty($arrayfields['e.date_delivery']['checked'])) {
1338 print '<td class="center">';
1339 print dol_print_date($db->jdate($obj->delivery_date), "day");
1340 /*$now = time();
1341 if ( ($now - $db->jdate($obj->date_reception)) > $conf->warnings->lim && $obj->statutid == 1 )
1342 {
1343 }*/
1344 print "</td>\n";
1345 if (!$i) {
1346 $totalarray['nbfield']++;
1347 }
1348 }
1349
1350 if (!empty($arrayfields['l.ref']['checked']) || !empty($arrayfields['l.date_delivery']['checked'])) {
1351 $reception->fetchObjectLinked($reception->id, $reception->element);
1352 $receiving = '';
1353 if (count($reception->linkedObjects['delivery']) > 0) {
1354 $receiving = reset($reception->linkedObjects['delivery']);
1355 }
1356
1357 if (!empty($arrayfields['l.ref']['checked'])) {
1358 // Ref
1359 print '<td>';
1360 print !empty($receiving) ? $receiving->getNomUrl($db) : '';
1361 print '</td>';
1362 }
1363
1364 if (!empty($arrayfields['l.date_delivery']['checked'])) {
1365 // Date received
1366 print '<td class="center">';
1367 print dol_print_date($db->jdate($obj->date_reception), "day");
1368 print '</td>'."\n";
1369 }
1370 }
1371
1372 // Extra fields
1373 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1374
1375 // Fields from hook
1376 $parameters = array('arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
1377 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
1378 print $hookmanager->resPrint;
1379 // Date creation
1380 if (!empty($arrayfields['e.datec']['checked'])) {
1381 print '<td class="center nowraponall">';
1382 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuserrel');
1383 print '</td>';
1384 if (!$i) {
1385 $totalarray['nbfield']++;
1386 }
1387 }
1388 // Date modification
1389 if (!empty($arrayfields['e.tms']['checked'])) {
1390 print '<td class="center nowraponall">';
1391 print dol_print_date($db->jdate($obj->date_modification), 'dayhour', 'tzuserrel');
1392 print '</td>';
1393 if (!$i) {
1394 $totalarray['nbfield']++;
1395 }
1396 }
1397 // Status
1398 if (!empty($arrayfields['e.fk_statut']['checked'])) {
1399 print '<td class="right nowrap">'.$reception->LibStatut($obj->status, 5).'</td>';
1400 if (!$i) {
1401 $totalarray['nbfield']++;
1402 }
1403 }
1404 // Billed
1405 if (!empty($arrayfields['e.billed']['checked'])) {
1406 print '<td class="center">'.yn($obj->billed).'</td>';
1407 if (!$i) {
1408 $totalarray['nbfield']++;
1409 }
1410 }
1411
1412 // Action column
1413 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1414 print '<td class="nowrap center">';
1415 if ($massactionbutton || $massaction) {
1416 // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1417 $selected = 0;
1418 if (in_array($obj->rowid, $arrayofselected)) {
1419 $selected = 1;
1420 }
1421 print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
1422 }
1423 print '</td>';
1424 }
1425 if (!$i) {
1426 $totalarray['nbfield']++;
1427 }
1428
1429 print "</tr>\n";
1430 }
1431 $i++;
1432}
1433
1434// If no record found
1435if ($num == 0) {
1436 $colspan = 1;
1437 foreach ($arrayfields as $key => $val) {
1438 if (!empty($val['checked'])) {
1439 $colspan++;
1440 }
1441 }
1442 print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
1443}
1444
1445// Show total line
1446include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
1447
1448$parameters = array('arrayfields' => $arrayfields, 'totalarray' => $totalarray, 'sql' => $sql);
1449$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
1450print $hookmanager->resPrint;
1451
1452print "</table>";
1453print "</div>";
1454print '</form>';
1455
1456$db->free($resql);
1457
1458$hidegeneratedfilelistifempty = 1;
1459if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
1460 $hidegeneratedfilelistifempty = 0;
1461}
1462
1463// Show list of available documents
1464$urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
1465$urlsource .= str_replace('&amp;', '&', $param);
1466
1467$filedir = $diroutputmassaction;
1468$genallowed = $user->hasRight('reception', 'lire');
1469$delallowed = $user->hasRight('reception', 'creer');
1470$title = '';
1471
1472print $formfile->showdocuments('massfilesarea_receipts', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
1473
1474// End of page
1475llxFooter();
1476$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage absolute discounts.
Class to manage standard extra fields.
Class to manage suppliers invoices.
Class to build HTML component for third parties management Only common components are here.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage receptions.
Class to manage third parties objects (customers, suppliers, prospects...)
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
llxFooter()
Footer empty.
Definition document.php:107
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.