dolibarr 21.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
6 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
8 * Copyright (C) 2010-2020 Juanjo Menent <jmenent@2byte.es>
9 * Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
10 * Copyright (C) 2021-2024 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
12 * Copyright (C) 2020 Open-Dsi <support@open-dsi.fr>
13 * Copyright (C) 2022 Anthony Berton <anthony.berton@bb2a.fr>
14 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
36// Load Dolibarr environment
37require '../main.inc.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
42require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
43require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
44require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
45require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
46require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
47if (isModEnabled('invoice')) {
48 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
49 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
50}
51if (isModEnabled("propal")) {
52 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
53}
54if (isModEnabled('order')) {
55 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
56}
57if (isModEnabled("shipping")) {
58 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
59}
60if (isModEnabled('contract')) {
61 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
62}
63if (isModEnabled('member')) {
64 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
65}
66if (isModEnabled('intervention')) {
67 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
68}
69if (isModEnabled('accounting')) {
70 require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
71 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
72}
73
83// Load translation files required by the page
84$langs->loadLangs(array('companies', 'banks'));
85
86if (isModEnabled('contract')) {
87 $langs->load("contracts");
88}
89if (isModEnabled('order')) {
90 $langs->load("orders");
91}
92if (isModEnabled("shipping")) {
93 $langs->load("sendings");
94}
95if (isModEnabled('invoice')) {
96 $langs->load("bills");
97}
98if (isModEnabled('project')) {
99 $langs->load("projects");
100}
101if (isModEnabled('intervention')) {
102 $langs->load("interventions");
103}
104if (isModEnabled('notification')) {
105 $langs->load("mails");
106}
107
108$action = GETPOST('action', 'aZ09');
109
110$id = (GETPOSTINT('socid') ? GETPOSTINT('socid') : GETPOSTINT('id'));
111
112$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
113$sortfield = GETPOST('sortfield', 'aZ09comma');
114$sortorder = GETPOST('sortorder', 'aZ09comma');
115$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
116if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
117 // If $page is not defined, or '' or -1 or if we click on clear filters
118 $page = 0;
119}
120$offset = $limit * $page;
121$pageprev = $page - 1;
122$pagenext = $page + 1;
123if (!$sortorder) {
124 $sortorder = "ASC";
125}
126if (!$sortfield) {
127 $sortfield = "nom";
128}
129$cancel = GETPOST('cancel', 'alpha');
130
131$object = new Client($db);
132$extrafields = new ExtraFields($db);
133$formfile = new FormFile($db);
134
135// fetch optionals attributes and labels
136$extrafields->fetch_name_optionals_label($object->table_element);
137
138// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
139$hookmanager->initHooks(array('thirdpartycomm', 'globalcard'));
140
141$now = dol_now();
142
143if ($id > 0 && empty($object->id)) {
144 // Load data of third party
145 $res = $object->fetch($id);
146 if ($object->id < 0) {
147 dol_print_error($db, $object->error, $object->errors);
148 }
149}
150if ($object->id > 0) {
151 if (!($object->client > 0) || !$user->hasRight('societe', 'lire')) {
153 }
154}
155
156// Security check
157if ($user->socid > 0) {
158 $id = $user->socid;
159}
160$result = restrictedArea($user, 'societe', $object->id, '&societe', '', 'fk_soc', 'rowid', 0);
161
162
163/*
164 * Actions
165 */
166$error = 0;
167
168$parameters = array('id' => $id, 'socid' => $id);
169$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some
170if ($reshook < 0) {
171 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
172}
173
174if (empty($reshook)) {
175 if ($cancel) {
176 $action = "";
177 }
178
179 // set accountancy code
180 if ($action == 'setcustomeraccountancycodegeneral') {
181 $result = $object->fetch($id);
182 $object->accountancy_code_customer_general = GETPOST("customeraccountancycodegeneral");
183 $result = $object->update($object->id, $user, 1, 1, 0);
184 if ($result < 0) {
185 setEventMessages($object->error, $object->errors, 'errors');
186 }
187 }
188
189 // Set accountancy code
190 if ($action == 'setcustomeraccountancycode' && $user->hasRight('societe', 'creer')) {
191 $result = $object->fetch($id);
192 $object->code_compta_client = GETPOST("customeraccountancycode");
193 $object->code_compta = $object->code_compta_client; // For Backward compatibility
194 $result = $object->update($object->id, $user, 1, 1, 0);
195 if ($result < 0) {
196 setEventMessages($object->error, $object->errors, 'errors');
197 $action = 'editcustomeraccountancycode';
198 }
199 }
200
201 // Payment terms of the settlement
202 if ($action == 'setconditions' && $user->hasRight('societe', 'creer')) {
203 $object->fetch($id);
204 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTINT('cond_reglement_id_deposit_percent'));
205 if ($result < 0) {
206 setEventMessages($object->error, $object->errors, 'errors');
207 }
208 }
209
210 // Payment mode
211 if ($action == 'setmode' && $user->hasRight('societe', 'creer')) {
212 $object->fetch($id);
213 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
214 if ($result < 0) {
215 setEventMessages($object->error, $object->errors, 'errors');
216 }
217 }
218
219 // Transport mode
220 if ($action == 'settransportmode' && $user->hasRight('societe', 'creer')) {
221 $object->fetch($id);
222 $result = $object->setTransportMode(GETPOST('transport_mode_id', 'alpha'));
223 if ($result < 0) {
224 setEventMessages($object->error, $object->errors, 'errors');
225 }
226 }
227
228 // Bank account
229 if ($action == 'setbankaccount' && $user->hasRight('societe', 'creer')) {
230 $object->fetch($id);
231 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
232 if ($result < 0) {
233 setEventMessages($object->error, $object->errors, 'errors');
234 }
235 }
236
237 // customer preferred shipping method
238 if ($action == 'setshippingmethod' && $user->hasRight('societe', 'creer')) {
239 $object->fetch($id);
240 $result = $object->setShippingMethod(GETPOSTINT('shipping_method_id'));
241 if ($result < 0) {
242 setEventMessages($object->error, $object->errors, 'errors');
243 }
244 }
245
246 // assujetissement a la TVA
247 if ($action == 'setassujtva' && $user->hasRight('societe', 'creer')) {
248 $object->fetch($id);
249 $object->tva_assuj = GETPOSTINT('assujtva_value');
250 $result = $object->update($object->id, $user);
251 if ($result < 0) {
252 setEventMessages($object->error, $object->errors, 'errors');
253 }
254 }
255
256 // set prospect level
257 if ($action == 'setprospectlevel' && $user->hasRight('societe', 'creer')) {
258 $object->fetch($id);
259 $object->fk_prospectlevel = GETPOST('prospect_level_id', 'alpha');
260 $result = $object->update($object->id, $user);
261 if ($result < 0) {
262 setEventMessages($object->error, $object->errors, 'errors');
263 }
264 }
265
266 // set communication status
267 if ($action == 'setstcomm' && $user->hasRight('societe', 'creer')) {
268 $object->fetch($id);
269 $object->stcomm_id = dol_getIdFromCode($db, GETPOST('stcomm', 'alpha'), 'c_stcomm');
270 $result = $object->update($object->id, $user);
271 if ($result < 0) {
272 setEventMessages($object->error, $object->errors, 'errors');
273 } else {
274 $result = $object->fetch($object->id);
275 }
276 }
277
278 // update outstandng limit
279 if ($action == 'setoutstanding_limit' && $user->hasRight('societe', 'creer')) {
280 $object->fetch($id);
281 $object->outstanding_limit = GETPOST('outstanding_limit');
282 $result = $object->update($object->id, $user);
283 if ($result < 0) {
284 setEventMessages($object->error, $object->errors, 'errors');
285 }
286 }
287
288 // update order min amount
289 if ($action == 'setorder_min_amount' && $user->hasRight('societe', 'creer')) {
290 $object->fetch($id);
291 $object->order_min_amount = price2num(GETPOST('order_min_amount', 'alpha'));
292 $result = $object->update($object->id, $user);
293 if ($result < 0) {
294 setEventMessages($object->error, $object->errors, 'errors');
295 }
296 }
297
298 // Set sales representatives
299 if ($action == 'set_salesrepresentatives' && $user->hasRight('societe', 'creer')) {
300 $object->fetch($id);
301 $result = $object->setSalesRep(GETPOST('commercial', 'array'));
302 }
303
304 if ($action == 'update_extras' && $user->hasRight('societe', 'creer')) {
305 $object->fetch($id);
306
307 $object->oldcopy = dol_clone($object, 2);
308
309 // Fill array 'array_options' with data from update form
310 $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
311 if ($ret < 0) {
312 $error++;
313 }
314 if (!$error) {
315 $result = $object->insertExtraFields('COMPANY_MODIFY');
316 if ($result < 0) {
317 setEventMessages($object->error, $object->errors, 'errors');
318 $error++;
319 }
320 }
321 if ($error) {
322 $action = 'edit_extras';
323 }
324 }
325
326 // warehouse
327 if ($action == 'setwarehouse' && $user->hasRight('societe', 'creer')) {
328 $result = $object->setWarehouse(GETPOSTINT('fk_warehouse'));
329 }
330}
331
332
333/*
334 * View
335 */
336
337$contactstatic = new Contact($db);
338$userstatic = new User($db);
339$form = new Form($db);
340$formcompany = new FormCompany($db);
341$project = new Project($db);
342
343$title = $langs->trans("ThirdParty")." - ".$langs->trans('Customer');
344if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/thirdpartynameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
345 $title = $object->name." - ".$langs->trans('Customer');
346}
347
348$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner';
349
350llxHeader('', $title, $help_url);
351
352if ($object->id > 0) {
354
355 print dol_get_fiche_head($head, 'customer', $langs->trans("ThirdParty"), -1, 'company');
356
357 $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
358
359 dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
360
361 print '<div class="fichecenter"><div class="fichehalfleft">';
362
363 print '<div class="underbanner clearboth"></div>';
364 print '<table class="border centpercent tableforfield">';
365
366 // Type Prospect/Customer/Supplier
367 print '<tr><td class="titlefield">'.$langs->trans('NatureOfThirdParty').'</td><td>';
368 print $object->getTypeUrl(1);
369 print '</td></tr>';
370
371 // Prefix
372 if (getDolGlobalString('SOCIETE_USEPREFIX')) { // Old not used prefix field
373 print '<tr><td>'.$langs->trans("Prefix").'</td><td>';
374 print($object->prefix_comm ? $object->prefix_comm : '&nbsp;');
375 print '</td></tr>';
376 }
377
378 if ($object->client) {
379 $langs->load("compta");
380
381 print '<tr><td>';
382 print $langs->trans('CustomerCode').'</td><td>';
384 $tmpcheck = $object->check_codeclient();
385 if ($tmpcheck != 0 && $tmpcheck != -5) {
386 print ' <span class="error">('.$langs->trans("WrongCustomerCode").')</span>';
387 }
388 print '</td></tr>';
389
390 if (isModEnabled('accounting')) {
391 $formaccounting = new FormAccounting($db);
392
393 print '<tr>';
394 print '<td>';
395 print $form->editfieldkey("CustomerAccountancyCodeGeneral", 'customeraccountancycodegeneral', length_accountg($object->accountancy_code_customer_general), $object, $user->hasRight('societe', 'creer'));
396 print '</td><td>';
397 if ($action == 'editcustomeraccountancycodegeneral' && $user->hasRight('societe', 'creer')) {
398 print $formaccounting->formAccountingAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->accountancy_code_customer_general, 'customeraccountancycodegeneral', 0, 1, '', 1);
399 } else {
400 if ($object->accountancy_code_customer_general > 0) {
401 $accountingaccount = new AccountingAccount($db);
402 $accountingaccount->fetch(0, $object->accountancy_code_customer_general, 1);
403
404 print $accountingaccount->getNomUrl(0, 1, 1, '', 1);
405 }
406 if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER')) {
407 if ($object->accountancy_code_customer_general > 0) {
408 print ' - ';
409 }
410 $accountingAccountByDefault = '<span class="opacitymedium">' . $langs->trans("AccountingAccountByDefaultShort") . ": " . length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER')) . '</span>';
411 print $accountingAccountByDefault;
412 }
413 }
414 print '</td>';
415 }
416
417 print '<tr>';
418 print '<td>';
419 print $form->editfieldkey("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta_client, $object, $user->hasRight('societe', 'creer'));
420 print '</td><td>';
421 print $form->editfieldval("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta_client, $object, $user->hasRight('societe', 'creer'));
422 print '</td>';
423 print '</tr>';
424 }
425
426 // This fields are used to know VAT to include in an invoice when the thirdparty is making a sale, so when it is a supplier.
427 // We don't need them into customer profile.
428 // Except for spain and localtax where localtax depends on buyer and not seller
429
430 // VAT is used
431 /*
432 print '<tr>';
433 print '<td class="nowrap">';
434 print $form->textwithpicto($langs->trans('VATIsUsed'),$langs->trans('VATIsUsedWhenSelling'));
435 print '</td>';
436 print '<td>';
437 print yn($object->tva_assuj);
438 print '</td>';
439 print '</tr>';
440 */
441
442 if ($mysoc->country_code == 'ES') {
443 // Local Taxes
444 if ($mysoc->localtax1_assuj == "1") {
445 print '<tr><td class="nowrap">'.$langs->transcountry("LocalTax1IsUsed", $mysoc->country_code).'</td><td>';
446 print yn($object->localtax1_assuj);
447 print '</td></tr>';
448 }
449 if ($mysoc->localtax1_assuj == "1") {
450 print '<tr><td class="nowrap">'.$langs->transcountry("LocalTax2IsUsed", $mysoc->country_code).'</td><td>';
451 print yn($object->localtax2_assuj);
452 print '</td></tr>';
453 }
454 }
455
456 // TVA Intra
457 print '<tr><td class="nowrap">'.$langs->trans('VATIntra').'</td><td>';
459 print '</td></tr>';
460
461 // default terms of the settlement
462 $langs->load('bills');
463 print '<tr><td>';
464 print '<table width="100%" class="nobordernopadding"><tr><td>';
465 print $langs->trans('PaymentConditions');
466 print '<td>';
467 if (($action != 'editconditions') && $user->hasRight('societe', 'creer')) {
468 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
469 }
470 print '</tr></table>';
471 print '</td><td>';
472 if ($action == 'editconditions') {
473 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
474 } else {
475 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'none', 0, '', 1, $object->deposit_percent);
476 }
477 print "</td>";
478 print '</tr>';
479
480 // Default payment mode
481 print '<tr><td class="nowrap">';
482 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
483 print $langs->trans('PaymentMode');
484 print '<td>';
485 if (($action != 'editmode') && $user->hasRight('societe', 'creer')) {
486 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
487 }
488 print '</tr></table>';
489 print '</td><td>';
490 if ($action == 'editmode') {
491 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
492 } else {
493 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->mode_reglement_id, 'none');
494 }
495 print "</td>";
496 print '</tr>';
497
498 if (isModEnabled("bank")) {
499 // Default bank account for payments
500 print '<tr><td class="nowrap">';
501 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
502 print $langs->trans('PaymentBankAccount');
503 print '<td>';
504 if (($action != 'editbankaccount') && $user->hasRight('societe', 'creer')) {
505 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
506 }
507 print '</tr></table>';
508 print '</td><td>';
509 if ($action == 'editbankaccount') {
510 $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->fk_account, 'fk_account', 1);
511 } else {
512 $form->formSelectAccount($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->fk_account, 'none');
513 }
514 print "</td>";
515 print '</tr>';
516 }
517
518 $isCustomer = ($object->client == 1 || $object->client == 3);
519
520 // Relative discounts (Discounts-Drawbacks-Rebates)
521 if ($isCustomer) {
522 print '<tr><td class="nowrap">';
523 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
524 print $langs->trans("CustomerRelativeDiscountShort");
525 print '<td><td class="right">';
526 if ($user->hasRight('societe', 'creer') && !$user->socid > 0) {
527 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$object->id).'&action=create&token='.newToken().'">'.img_edit($langs->trans("Modify")).'</a>';
528 }
529 print '</td></tr></table>';
530 print '</td><td>'.($object->remise_percent ? '<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$object->id.'">'.$object->remise_percent.'%</a>' : '').'</td>';
531 print '</tr>';
532
533 // Absolute discounts (Discounts-Drawbacks-Rebates)
534 print '<tr><td class="nowrap">';
535 print '<table width="100%" class="nobordernopadding">';
536 print '<tr><td class="nowrap">';
537 print $langs->trans("CustomerAbsoluteDiscountShort");
538 print '<td><td class="right">';
539 if ($user->hasRight('societe', 'creer') && !$user->socid > 0) {
540 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$object->id).'&action=create_remise&token='.newToken().'">'.img_edit($langs->trans("Modify")).'</a>';
541 }
542 print '</td></tr></table>';
543 print '</td>';
544 print '<td>';
545 $amount_discount = $object->getAvailableDiscounts();
546 if ($amount_discount < 0) {
547 dol_print_error($db, $object->error);
548 }
549 if ($amount_discount > 0) {
550 print '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$object->id).'&action=create&token='.newToken().'">'.price($amount_discount, 1, $langs, 1, -1, -1, $conf->currency).'</a>';
551 }
552 //else print $langs->trans("DiscountNone");
553 print '</td>';
554 print '</tr>';
555 }
556
557 $limit_field_type = '';
558 // Max outstanding bill
559 if ($object->client) {
560 print '<tr class="nowrap">';
561 print '<td>';
562 print $form->editfieldkey("OutstandingBill", 'outstanding_limit', $object->outstanding_limit, $object, $user->hasRight('societe', 'creer'));
563 print '</td><td>';
564 $limit_field_type = (getDolGlobalString('MAIN_USE_JQUERY_JEDITABLE')) ? 'numeric' : 'amount';
565 print $form->editfieldval("OutstandingBill", 'outstanding_limit', $object->outstanding_limit, $object, $user->hasRight('societe', 'creer'), $limit_field_type, ($object->outstanding_limit != '' ? price($object->outstanding_limit) : ''));
566 print '</td>';
567 print '</tr>';
568 }
569
570 if ($object->client) {
571 if (isModEnabled('order') && getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT')) {
572 print '<!-- Minimum amount for orders -->'."\n";
573 print '<tr class="nowrap">';
574 print '<td>';
575 print $form->editfieldkey("OrderMinAmount", 'order_min_amount', $object->order_min_amount, $object, $user->hasRight('societe', 'creer'));
576 print '</td><td>';
577 print $form->editfieldval("OrderMinAmount", 'order_min_amount', $object->order_min_amount, $object, $user->hasRight('societe', 'creer'), $limit_field_type, ($object->order_min_amount != '' ? price($object->order_min_amount) : ''));
578 print '</td>';
579 print '</tr>';
580 }
581 }
582
583
584 // Multiprice level
585 if (getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
586 print '<tr><td class="nowrap">';
587 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
588 print $langs->trans("PriceLevel");
589 print '<td><td class="right">';
590 if ($user->hasRight('societe', 'creer')) {
591 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/comm/multiprix.php?id='.$object->id.'">'.img_edit($langs->trans("Modify")).'</a>';
592 }
593 print '</td></tr></table>';
594 print '</td><td>';
595 print $object->price_level;
596 $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.$object->price_level;
597 if (getDolGlobalString($keyforlabel)) {
598 print ' - '.$langs->trans(getDolGlobalString($keyforlabel));
599 }
600 print "</td>";
601 print '</tr>';
602 }
603
604 // Warehouse
605 if (isModEnabled('stock') && getDolGlobalString('SOCIETE_ASK_FOR_WAREHOUSE')) {
606 $langs->load('stocks');
607 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
608 $formproduct = new FormProduct($db);
609 print '<tr class="nowrap">';
610 print '<td>';
611 print $form->editfieldkey("Warehouse", 'warehouse', '', $object, $user->hasRight('societe', 'creer'));
612 print '</td><td>';
613 if ($action == 'editwarehouse') {
614 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_warehouse, 'fk_warehouse', 1);
615 } else {
616 if ($object->fk_warehouse > 0) {
617 print img_picto('', 'stock', 'class="paddingrightonly"');
618 }
619 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_warehouse, 'none');
620 }
621 print '</td>';
622 print '</tr>';
623 }
624
625 // Preferred shipping Method
626 if (getDolGlobalString('SOCIETE_ASK_FOR_SHIPPING_METHOD')) {
627 print '<tr><td class="nowrap">';
628 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
629 print $langs->trans('SendingMethod');
630 print '<td>';
631 if (($action != 'editshipping') && $user->hasRight('societe', 'creer')) {
632 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editshipping&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
633 }
634 print '</tr></table>';
635 print '</td><td>';
636 if ($action == 'editshipping') {
637 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1);
638 } else {
639 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->shipping_method_id, 'none');
640 }
641 print "</td>";
642 print '</tr>';
643 }
644
645 if (isModEnabled('intracommreport')) {
646 // Transport mode by default
647 print '<tr><td class="nowrap">';
648 print '<table class="centpercent nobordernopadding"><tr><td class="nowrap">';
649 print $langs->trans('IntracommReportTransportMode');
650 print '<td>';
651 if (($action != 'edittransportmode') && $user->hasRight('societe', 'creer')) {
652 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edittransportmode&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
653 }
654 print '</tr></table>';
655 print '</td><td>';
656 if ($action == 'edittransportmode') {
657 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?socid='.$object->id, (!empty($object->transport_mode_id) ? $object->transport_mode_id : ''), 'transport_mode_id', 1);
658 } else {
659 $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?socid='.$object->id, (!empty($object->transport_mode_id) ? $object->transport_mode_id : ''), 'none');
660 }
661 print "</td>";
662 print '</tr>';
663 }
664
665 // Categories
666 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
667 $langs->load("categories");
668 print '<tr><td>'.$langs->trans("CustomersCategoriesShort").'</td>';
669 print '<td>';
670 print $form->showCategories($object->id, Categorie::TYPE_CUSTOMER, 1);
671 print "</td></tr>";
672 }
673
674 // Other attributes
675 $parameters = array('socid' => $object->id);
676 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
677
678 // Sales representative
679 include DOL_DOCUMENT_ROOT.'/societe/tpl/linesalesrepresentative.tpl.php';
680
681 // Module Adherent
682 if (isModEnabled('member')) {
683 $langs->load("members");
684 $langs->load("users");
685
686 print '<tr><td class="titlefield">'.$langs->trans("LinkedToDolibarrMember").'</td>';
687 print '<td>';
688 $adh = new Adherent($db);
689 $result = $adh->fetch(0, '', $object->id);
690 if ($result > 0) {
691 $adh->ref = $adh->getFullName($langs);
692 print $adh->getNomUrl(-1);
693 } else {
694 print '<span class="opacitymedium">'.$langs->trans("ThirdpartyNotLinkedToMember").'</span>';
695 }
696 print '</td>';
697 print "</tr>\n";
698 }
699
700 print "</table>";
701
702 print '</div><div class="fichehalfright">';
703
704 // Prospection level and status
705 if ($object->client == 2 || $object->client == 3) {
706 print '<div class="underbanner clearboth"></div>';
707 print '<table class="border centpercent tableforfield">';
708
709 // Level of prospection
710 print '<tr><td class="titlefield nowrap">';
711 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
712 print $langs->trans('ProspectLevel');
713 print '<td>';
714 if ($action != 'editlevel' && $user->hasRight('societe', 'creer')) {
715 print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editlevel&token='.newToken().'&socid='.$object->id.'">'.img_edit($langs->trans('Modify'), 1).'</a></td>';
716 }
717 print '</tr></table>';
718 print '</td><td>';
719 if ($action == 'editlevel') {
720 $formcompany->form_prospect_level($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->fk_prospectlevel, 'prospect_level_id', 1);
721 } else {
722 print $object->getLibProspLevel();
723 }
724 print "</td>";
725 print '</tr>';
726
727 // Status of prospection
728 $object->loadCacheOfProspStatus();
729 print '<tr><td>'.$langs->trans("StatusProsp").'</td><td>'.$object->getLibProspCommStatut(4, $object->cacheprospectstatus[$object->stcomm_id]['label']);
730 print ' &nbsp; &nbsp; ';
731 print '<div class="floatright">';
732 foreach ($object->cacheprospectstatus as $key => $val) {
733 $titlealt = 'default';
734 if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) {
735 $titlealt = $val['label'];
736 }
737 if ($object->stcomm_id != $val['id']) {
738 print '<a class="pictosubstatus reposition" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&stcomm='.$val['code'].'&action=setstcomm&token='.newToken().'">'.img_action($titlealt, $val['code'], $val['picto']).'</a>';
739 }
740 }
741 print '</div></td></tr>';
742 print "</table>";
743
744 print '<br>';
745 } else {
746 print '<div class="underbanner underbanner-before-box clearboth"></div><br>';
747 }
748
749 $boxstat = '';
750
751 // Max nb of elements in lists
752 $MAXLIST = getDolGlobalString('MAIN_SIZE_SHORTLIST_LIMIT');
753
754 // Link summary/status board
755 $boxstat .= '<div class="box divboxtable box-halfright">';
756 $boxstat .= '<table summary="'.dol_escape_htmltag($langs->trans("DolibarrStateBoard")).'" class="border boxtable boxtablenobottom boxtablenotop boxtablenomarginbottom centpercent">';
757 $boxstat .= '<tr class="impair nohover"><td colspan="2" class="tdboxstats nohover">';
758
759 if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
760 // Box proposals
761 $tmp = $object->getOutstandingProposals();
762 $outstandingOpened = $tmp['opened'];
763 $outstandingTotal = $tmp['total_ht'];
764 $outstandingTotalIncTax = $tmp['total_ttc'];
765 $text = $langs->trans("OverAllProposals");
766 $link = DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->id;
767 $icon = 'bill';
768 if ($link) {
769 $boxstat .= '<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
770 }
771 $boxstat .= '<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
772 $boxstat .= '<span class="boxstatstext">'.img_object("", $icon).' <span>'.$text.'</span></span><br>';
773 $boxstat .= '<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
774 $boxstat .= '</div>';
775 if ($link) {
776 $boxstat .= '</a>';
777 }
778 }
779
780 if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
781 // Box orders
782 $tmp = $object->getOutstandingOrders();
783 $outstandingOpened = $tmp['opened'];
784 $outstandingTotal = $tmp['total_ht'];
785 $outstandingTotalIncTax = $tmp['total_ttc'];
786 $text = $langs->trans("OverAllOrders");
787 $link = DOL_URL_ROOT.'/commande/list.php?socid='.$object->id;
788 $icon = 'bill';
789 if ($link) {
790 $boxstat .= '<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
791 }
792 $boxstat .= '<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
793 $boxstat .= '<span class="boxstatstext">'.img_object("", $icon).' <span>'.$text.'</span></span><br>';
794 $boxstat .= '<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
795 $boxstat .= '</div>';
796 if ($link) {
797 $boxstat .= '</a>';
798 }
799 }
800
801 if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
802 // Box invoices
803 $tmp = $object->getOutstandingBills('customer', 0);
804 $outstandingOpened = $tmp['opened'];
805 $outstandingTotal = $tmp['total_ht'];
806 $outstandingTotalIncTax = $tmp['total_ttc'];
807
808 $text = $langs->trans("OverAllInvoices");
809 $link = DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->id;
810 $icon = 'bill';
811 if ($link) {
812 $boxstat .= '<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
813 }
814 $boxstat .= '<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
815 $boxstat .= '<span class="boxstatstext">'.img_object("", $icon).' <span>'.$text.'</span></span><br>';
816 $boxstat .= '<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
817 $boxstat .= '</div>';
818 if ($link) {
819 $boxstat .= '</a>';
820 }
821
822 // Box outstanding bill
823 $warn = '';
824 if ($object->outstanding_limit != '' && $object->outstanding_limit < $outstandingOpened) {
825 $warn = ' '.img_warning($langs->trans("OutstandingBillReached"));
826 }
827 $text = $langs->trans("CurrentOutstandingBill");
828 $link = DOL_URL_ROOT.'/compta/recap-compta.php?socid='.$object->id;
829 $icon = 'bill';
830 if ($link) {
831 $boxstat .= '<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
832 }
833 $boxstat .= '<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
834 $boxstat .= '<span class="boxstatstext">'.img_object("", $icon).' <span>'.$text.'</span></span><br>';
835 $boxstat .= '<span class="boxstatsindicator'.($outstandingOpened > 0 ? ' amountremaintopay' : '').'">'.price($outstandingOpened, 1, $langs, 1, -1, -1, $conf->currency).$warn.'</span>';
836 $boxstat .= '</div>';
837 if ($link) {
838 $boxstat .= '</a>';
839 }
840
841 $tmp = $object->getOutstandingBills('customer', 1);
842 $outstandingOpenedLate = $tmp['opened'];
843 if ($outstandingOpened != $outstandingOpenedLate && !empty($outstandingOpenedLate)) {
844 $warn = '';
845 if ($object->outstanding_limit != '' && $object->outstanding_limit < $outstandingOpenedLate) {
846 $warn = ' '.img_warning($langs->trans("OutstandingBillReached"));
847 }
848 $text = $langs->trans("CurrentOutstandingBillLate");
849 $link = DOL_URL_ROOT.'/compta/recap-compta.php?socid='.$object->id;
850 $icon = 'bill';
851 if ($link) {
852 $boxstat .= '<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
853 }
854 $boxstat .= '<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
855 $boxstat .= '<span class="boxstatstext">'.img_object("", $icon).' <span>'.$text.'</span></span><br>';
856 $boxstat .= '<span class="boxstatsindicator'.($outstandingOpenedLate > 0 ? ' amountremaintopay' : '').'">'.price($outstandingOpenedLate, 1, $langs, 1, -1, -1, $conf->currency).$warn.'</span>';
857 $boxstat .= '</div>';
858 if ($link) {
859 $boxstat .= '</a>';
860 }
861 }
862 }
863
864 $parameters = array();
865 $reshook = $hookmanager->executeHooks('addMoreBoxStatsCustomer', $parameters, $object, $action);
866 if (empty($reshook)) {
867 $boxstat .= $hookmanager->resPrint;
868 }
869
870 $boxstat .= '</td></tr>';
871 $boxstat .= '</table>';
872 $boxstat .= '</div>';
873
874 print $boxstat;
875
876
877 /*
878 * Latest proposals
879 */
880 if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
881 $langs->load("propal");
882
883 $sql = "SELECT s.nom, s.rowid, p.rowid as propalid, p.fk_projet, p.fk_statut, p.total_ht";
884 $sql .= ", p.total_tva";
885 $sql .= ", p.total_ttc";
886 $sql .= ", p.ref, p.ref_client, p.remise";
887 $sql .= ", p.datep as dp, p.fin_validite as date_limit, p.entity";
888 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c";
889 $sql .= " WHERE p.fk_soc = s.rowid AND p.fk_statut = c.id";
890 $sql .= " AND s.rowid = ".((int) $object->id);
891 $sql .= " AND p.entity IN (".getEntity('propal').")";
892 $sql .= " ORDER BY p.datep DESC";
893
894 $resql = $db->query($sql);
895 if ($resql) {
896 $propal_static = new Propal($db);
897
898 $num = $db->num_rows($resql);
899 if ($num > 0) {
900 print '<div class="div-table-responsive-no-min">';
901 print '<table class="noborder centpercent lastrecordtable">';
902
903 print '<tr class="liste_titre">';
904 print '<td colspan="5"><table width="100%" class="nobordernopadding"><tr><td>'.$langs->trans("LastPropals", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllPropals").'</span><span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
905 print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/comm/propal/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"), 'stats').'</a></td>';
906 print '</tr></table></td>';
907 print '</tr>';
908 }
909
910 $i = 0;
911 while ($i < $num && $i < $MAXLIST) {
912 $objp = $db->fetch_object($resql);
913
914 print '<tr class="oddeven">';
915 print '<td class="nowraponall">';
916 $propal_static->id = $objp->propalid;
917 $propal_static->ref = $objp->ref;
918 $propal_static->ref_client = $objp->ref_client; // deprecated
919 $propal_static->ref_customer = $objp->ref_client;
920 $propal_static->fk_project = $objp->fk_projet;
921 $propal_static->total_ht = $objp->total_ht;
922 $propal_static->total_tva = $objp->total_tva;
923 $propal_static->total_ttc = $objp->total_ttc;
924 print $propal_static->getNomUrl(1);
925
926 // Preview
927 $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
928 $file_list = null;
929 if (!empty($filedir)) {
930 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
931 }
932 if (is_array($file_list) && !empty($file_list)) {
933 // Defined relative dir to DOL_DATA_ROOT
934 $relativedir = '';
935 if ($filedir) {
936 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
937 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
938 }
939 // Get list of files stored into database for same relative directory
940 if ($relativedir) {
941 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
942 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
943
944 //var_dump($sortfield.' - '.$sortorder);
945 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
946 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
947 }
948 }
949 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
950 print $formfile->showPreview($file_list, $propal_static->element, $relativepath, 0);
951 }
952 print '</td><td class="left">';
953 if ($propal_static->fk_project > 0) {
954 $project->fetch($propal_static->fk_project);
955 print $project->getNomUrl(1);
956 }
957 // $filename = dol_sanitizeFileName($objp->ref);
958 // $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
959 // $urlsource = '/comm/propal/card.php?id='.$objp->cid;
960 // print $formfile->getDocumentsLink($propal_static->element, $filename, $filedir);
961 if (($db->jdate($objp->date_limit) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == $propal_static::STATUS_VALIDATED) {
962 print " ".img_warning();
963 }
964 print '</td><td class="right" width="80px">'.dol_print_date($db->jdate($objp->dp), 'day')."</td>\n";
965 print '<td class="right nowraponall">'.price($objp->total_ht).'</td>';
966 print '<td class="right" style="min-width: 60px" class="nowrap">'.$propal_static->LibStatut($objp->fk_statut, 5).'</td></tr>';
967 $i++;
968 }
969 $db->free($resql);
970
971 if ($num > 0) {
972 print "</table>";
973 print '</div>';
974 }
975 } else {
976 dol_print_error($db);
977 }
978 }
979
980 $orders2invoice = null;
981 $param = "";
982 /*
983 * Latest orders
984 */
985 if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
986 $sql = "SELECT s.nom, s.rowid";
987 $sql .= ", c.rowid as cid, c.entity, c.fk_projet, c.total_ht";
988 $sql .= ", c.total_tva";
989 $sql .= ", c.total_ttc";
990 $sql .= ", c.ref, c.ref_client, c.fk_statut, c.facture";
991 $sql .= ", c.date_commande as dc";
992 $sql .= ", c.facture as billed";
993 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c";
994 $sql .= " WHERE c.fk_soc = s.rowid ";
995 $sql .= " AND s.rowid = ".((int) $object->id);
996 $sql .= " AND c.entity IN (".getEntity('commande').')';
997 $sql .= " ORDER BY c.date_commande DESC";
998
999 $resql = $db->query($sql);
1000 if ($resql) {
1001 $commande_static = new Commande($db);
1002
1003 $num = $db->num_rows($resql);
1004 if ($num > 0) {
1005 // Check if there are orders billable
1006 $sql2 = 'SELECT s.nom, s.rowid as socid, s.client, c.rowid, c.ref, c.total_ht, c.ref_client,';
1007 $sql2 .= ' c.date_valid, c.date_commande, c.date_livraison, c.fk_statut, c.facture as billed';
1008 $sql2 .= ' FROM '.MAIN_DB_PREFIX.'societe as s';
1009 $sql2 .= ', '.MAIN_DB_PREFIX.'commande as c';
1010 $sql2 .= ' WHERE c.fk_soc = s.rowid';
1011 $sql2 .= ' AND s.rowid = '.((int) $object->id);
1012 // Show orders with status validated, shipping started and delivered (well any order we can bill)
1013 $sql2 .= " AND ((c.fk_statut IN (1,2)) OR (c.fk_statut = 3 AND c.facture = 0))";
1014
1015 $resql2 = $db->query($sql2);
1016 $orders2invoice = $db->num_rows($resql2);
1017 $db->free($resql2);
1018
1019 print '<div class="div-table-responsive-no-min">';
1020 print '<table class="noborder centpercent lastrecordtable">';
1021
1022 print '<tr class="liste_titre">';
1023 print '<td colspan="5"><table width="100%" class="nobordernopadding"><tr><td>'.$langs->trans("LastCustomerOrders", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllOrders").'</span><span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
1024 print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/commande/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"), 'stats').'</a></td>';
1025 print '</tr></table></td>';
1026 print '</tr>';
1027 }
1028
1029 $i = 0;
1030 while ($i < $num && $i < $MAXLIST) {
1031 $objp = $db->fetch_object($resql);
1032
1033 $commande_static->id = $objp->cid;
1034 $commande_static->ref = $objp->ref;
1035 $commande_static->ref_client = $objp->ref_client;
1036 $commande_static->fk_project = $objp->fk_projet;
1037 $commande_static->total_ht = $objp->total_ht;
1038 $commande_static->total_tva = $objp->total_tva;
1039 $commande_static->total_ttc = $objp->total_ttc;
1040 $commande_static->billed = $objp->billed;
1041
1042 print '<tr class="oddeven">';
1043 print '<td class="nowraponall">';
1044 print $commande_static->getNomUrl(1);
1045 // Preview
1046 $filedir = $conf->commande->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1047 $file_list = null;
1048 if (!empty($filedir)) {
1049 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
1050 }
1051 if (is_array($file_list) && !empty($file_list)) {
1052 // Defined relative dir to DOL_DATA_ROOT
1053 $relativedir = '';
1054 if ($filedir) {
1055 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
1056 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1057 }
1058 // Get list of files stored into database for same relative directory
1059 if ($relativedir) {
1060 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
1061 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
1062
1063 //var_dump($sortfield.' - '.$sortorder);
1064 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1065 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
1066 }
1067 }
1068 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
1069 print $formfile->showPreview($file_list, $commande_static->element, $relativepath, 0, $param);
1070 }
1071 print '</td><td class="left">';
1072 if ($commande_static->fk_project > 0) {
1073 $project->fetch($commande_static->fk_project);
1074 print $project->getNomUrl(1);
1075 }
1076 // $filename = dol_sanitizeFileName($objp->ref);
1077 // $filedir = $conf->order->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1078 // $urlsource = '/commande/card.php?id='.$objp->cid;
1079 // print $formfile->getDocumentsLink($commande_static->element, $filename, $filedir);
1080 print '</td>';
1081
1082 print '<td class="right" width="80px">'.dol_print_date($db->jdate($objp->dc), 'day')."</td>\n";
1083 print '<td class="right nowraponall">'.price($objp->total_ht).'</td>';
1084 print '<td class="right" style="min-width: 60px" class="nowrap">'.$commande_static->LibStatut($objp->fk_statut, $objp->facture, 5).'</td></tr>';
1085 $i++;
1086 }
1087 $db->free($resql);
1088
1089 if ($num > 0) {
1090 print "</table>";
1091 print '</div>';
1092 }
1093 } else {
1094 dol_print_error($db);
1095 }
1096 }
1097
1098 /*
1099 * Latest shipments
1100 */
1101 if (isModEnabled("shipping") && $user->hasRight('expedition', 'lire')) {
1102 $sql = 'SELECT e.rowid as id';
1103 $sql .= ', e.ref, e.entity, e.fk_projet';
1104 $sql .= ', e.date_creation';
1105 $sql .= ', e.fk_statut as statut';
1106 $sql .= ', s.nom';
1107 $sql .= ', s.rowid as socid';
1108 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."expedition as e";
1109 $sql .= " WHERE e.fk_soc = s.rowid AND s.rowid = ".((int) $object->id);
1110 $sql .= " AND e.entity IN (".getEntity('expedition').")";
1111 $sql .= ' GROUP BY e.rowid';
1112 $sql .= ', e.ref, e.entity, e.fk_projet';
1113 $sql .= ', e.date_creation';
1114 $sql .= ', e.fk_statut';
1115 $sql .= ', s.nom';
1116 $sql .= ', s.rowid';
1117 $sql .= " ORDER BY e.date_creation DESC";
1118
1119 $resql = $db->query($sql);
1120 if ($resql) {
1121 $sendingstatic = new Expedition($db);
1122
1123 $num = $db->num_rows($resql);
1124 if ($num > 0) {
1125 print '<div class="div-table-responsive-no-min">';
1126 print '<table class="noborder centpercent lastrecordtable">';
1127
1128 print '<tr class="liste_titre">';
1129 print '<td colspan="5"><table class="centpercent nobordernopadding"><tr><td>'.$langs->trans("LastSendings", ($num < $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/expedition/list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllSendings").'</span><span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
1130 print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/expedition/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"), 'stats').'</a></td>';
1131 print '</tr></table></td>';
1132 print '</tr>';
1133 }
1134
1135 $i = 0;
1136 while ($i < $num && $i < $MAXLIST) {
1137 $objp = $db->fetch_object($resql);
1138
1139 $sendingstatic->id = $objp->id;
1140 $sendingstatic->ref = $objp->ref;
1141 $sendingstatic->fk_project = $objp->fk_projet;
1142
1143 print '<tr class="oddeven">';
1144 print '<td class="nowraponall">';
1145 print $sendingstatic->getNomUrl(1);
1146 // Preview
1147 $filedir = $conf->expedition->multidir_output[$objp->entity].'/sending/'.dol_sanitizeFileName($objp->ref);
1148 $file_list = null;
1149 if (!empty($filedir)) {
1150 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
1151 }
1152 if (is_array($file_list) && !empty($file_list)) {
1153 // Defined relative dir to DOL_DATA_ROOT
1154 $relativedir = '';
1155 if ($filedir) {
1156 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
1157 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1158 }
1159 // Get list of files stored into database for same relative directory
1160 if ($relativedir) {
1161 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
1162 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
1163
1164 //var_dump($sortfield.' - '.$sortorder);
1165 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1166 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
1167 }
1168 }
1169 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
1170 print $formfile->showPreview($file_list, $sendingstatic->table_element, $relativepath, 0, $param);
1171 }
1172 print '</td><td class="left">';
1173 if ($sendingstatic->fk_project > 0) {
1174 $project->fetch($sendingstatic->fk_project);
1175 print $project->getNomUrl(1);
1176 }
1177 // $filename = dol_sanitizeFileName($objp->ref);
1178 // $filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1179 // $urlsource = '/expedition/card.php?id='.$objp->cid;
1180 // print $formfile->getDocumentsLink($sendingstatic->element, $filename, $filedir);
1181 print '</td>';
1182 if ($objp->date_creation > 0) {
1183 print '<td class="right" width="80px">'.dol_print_date($db->jdate($objp->date_creation), 'day').'</td>';
1184 } else {
1185 print '<td class="right"><b>!!!</b></td>';
1186 }
1187
1188 print '<td class="nowrap right">'.$sendingstatic->LibStatut($objp->statut, 5).'</td>';
1189 print "</tr>\n";
1190 $i++;
1191 }
1192 $db->free($resql);
1193
1194 if ($num > 0) {
1195 print "</table>";
1196 print '</div>';
1197 }
1198 } else {
1199 dol_print_error($db);
1200 }
1201 }
1202
1203 /*
1204 * Latest contracts
1205 */
1206 if (isModEnabled('contract') && $user->hasRight('contrat', 'lire')) {
1207 $sql = "SELECT s.nom, s.rowid, c.rowid as id, c.ref as ref, c.fk_projet, c.statut as contract_status, c.datec as dc, c.date_contrat as dcon, c.ref_customer as refcus, c.ref_supplier as refsup, c.entity,";
1208 $sql .= " c.last_main_doc, c.model_pdf";
1209 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c";
1210 $sql .= " WHERE c.fk_soc = s.rowid ";
1211 $sql .= " AND s.rowid = ".((int) $object->id);
1212 $sql .= " AND c.entity IN (".getEntity('contract').")";
1213 $sql .= " ORDER BY c.datec DESC";
1214
1215 $resql = $db->query($sql);
1216 if ($resql) {
1217 $contrat = new Contrat($db);
1218
1219 $num = $db->num_rows($resql);
1220 if ($num > 0) {
1221 print '<div class="div-table-responsive-no-min">';
1222 print '<table class="noborder centpercent lastrecordtable">';
1223
1224 print '<tr class="liste_titre">';
1225 print '<td colspan="6"><table width="100%" class="nobordernopadding"><tr><td>'.$langs->trans("LastContracts", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td>';
1226 print '<td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->id.'">'.$langs->trans("AllContracts").'<span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
1227 //print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/contract/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"),'stats').'</a></td>';
1228 print '</tr></table></td>';
1229 print '</tr>';
1230 }
1231
1232 $i = 0;
1233 while ($i < $num && $i < $MAXLIST) {
1234 $objp = $db->fetch_object($resql);
1235
1236 $contrat->id = $objp->id;
1237 $contrat->ref = $objp->ref ? $objp->ref : $objp->id;
1238 $contrat->ref_customer = $objp->refcus;
1239 $contrat->ref_supplier = $objp->refsup;
1240 $contrat->fk_project = $objp->fk_projet;
1241 $contrat->statut = $objp->contract_status;
1242 $contrat->status = $objp->contract_status;
1243 $contrat->last_main_doc = $objp->last_main_doc;
1244 $contrat->model_pdf = $objp->model_pdf;
1245 $contrat->fetch_lines();
1246
1247 $late = '';
1248 foreach ($contrat->lines as $line) {
1249 if ($contrat->status == Contrat::STATUS_VALIDATED && $line->statut == ContratLigne::STATUS_OPEN) {
1250 if (((!empty($line->date_end) ? $line->date_end : 0) + $conf->contrat->services->expires->warning_delay) < $now) {
1251 $late = img_warning($langs->trans("Late"));
1252 }
1253 }
1254 }
1255
1256 print '<tr class="oddeven">';
1257 print '<td class="nowraponall">';
1258 print $contrat->getNomUrl(1, 12);
1259 if (!empty($contrat->model_pdf)) {
1260 // Preview
1261 $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1262 $file_list = null;
1263 if (!empty($filedir)) {
1264 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
1265 }
1266 if (is_array($file_list) && !empty($file_list)) {
1267 // Defined relative dir to DOL_DATA_ROOT
1268 $relativedir = '';
1269 if ($filedir) {
1270 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
1271 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1272 }
1273 // Get list of files stored into database for same relative directory
1274 if ($relativedir) {
1275 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
1276 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
1277
1278 //var_dump($sortfield.' - '.$sortorder);
1279 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1280 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
1281 }
1282 }
1283 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
1284 print $formfile->showPreview($file_list, $contrat->element, $relativepath, 0);
1285 }
1286 }
1287 // $filename = dol_sanitizeFileName($objp->ref);
1288 // $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1289 // $urlsource = '/contrat/card.php?id='.$objp->cid;
1290 // print $formfile->getDocumentsLink($contrat->element, $filename, $filedir);
1291 print $late;
1292 print '</td><td class="tdoverflowmax100">';
1293 if ($contrat->fk_project > 0) {
1294 $project->fetch($contrat->fk_project);
1295 print $project->getNomUrl(1);
1296 }
1297 print "</td>\n";
1298 print '<td class="nowrap">';
1299 print dol_trunc(strtolower(get_class($object)) == strtolower(Client::class) ? $objp->refcus : $objp->refsup, 12);
1300 print "</td>\n";
1301 //print '<td class="right" width="80px"><span title="'.$langs->trans("DateCreation").'">'.dol_print_date($db->jdate($objp->dc), 'day')."</span></td>\n";
1302 print '<td class="right" width="80px"><span title="'.$langs->trans("DateContract").'">'.dol_print_date($db->jdate($objp->dcon), 'day')."</span></td>\n";
1303 print '<td width="20">&nbsp;</td>';
1304 print '<td class="nowraponall right">';
1305 print $contrat->getLibStatut(4);
1306 print "</td>\n";
1307 print '</tr>';
1308 $i++;
1309 }
1310 $db->free($resql);
1311
1312 if ($num > 0) {
1313 print "</table>";
1314 print '</div>';
1315 }
1316 } else {
1317 dol_print_error($db);
1318 }
1319 }
1320
1321 /*
1322 * Latest interventions
1323 */
1324 if (isModEnabled('intervention') && $user->hasRight('ficheinter', 'lire')) {
1325 $sql = "SELECT s.nom, s.rowid, f.rowid as id, f.ref, f.fk_projet, f.fk_statut, f.duree as duration, f.datei as startdate, f.entity";
1326 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as f";
1327 $sql .= " WHERE f.fk_soc = s.rowid";
1328 $sql .= " AND s.rowid = ".((int) $object->id);
1329 $sql .= " AND f.entity IN (".getEntity('intervention').")";
1330 $sql .= " ORDER BY f.tms DESC";
1331
1332 $resql = $db->query($sql);
1333 if ($resql) {
1334 $fichinter_static = new Fichinter($db);
1335
1336 $num = $db->num_rows($resql);
1337 if ($num > 0) {
1338 print '<div class="div-table-responsive-no-min">';
1339 print '<table class="noborder centpercent lastrecordtable">';
1340
1341 print '<tr class="liste_titre">';
1342 print '<td colspan="4"><table class="centpercent nobordernopadding"><tr><td>'.$langs->trans("LastInterventions", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/fichinter/list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllInterventions").'</span><span class="badge marginleftonlyshort">'.$num.'</span></td>';
1343 print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/fichinter/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"), 'stats').'</a></td>';
1344 print '</tr></table></td>';
1345 print '</tr>';
1346 }
1347
1348 $i = 0;
1349 while ($i < $num && $i < $MAXLIST) {
1350 $objp = $db->fetch_object($resql);
1351
1352 $fichinter_static->id = $objp->id;
1353 $fichinter_static->ref = $objp->ref;
1354 $fichinter_static->statut = $objp->fk_statut;
1355 $fichinter_static->fk_project = $objp->fk_projet;
1356
1357 print '<tr class="oddeven">';
1358 print '<td class="nowraponall">';
1359 print $fichinter_static->getNomUrl(1);
1360 // Preview
1361 $filedir = $conf->ficheinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1362 $file_list = null;
1363 if (!empty($filedir)) {
1364 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
1365 }
1366 if (is_array($file_list) && !empty($file_list)) {
1367 // Defined relative dir to DOL_DATA_ROOT
1368 $relativedir = '';
1369 if ($filedir) {
1370 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
1371 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1372 }
1373 // Get list of files stored into database for same relative directory
1374 if ($relativedir) {
1375 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
1376 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
1377
1378 //var_dump($sortfield.' - '.$sortorder);
1379 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1380 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
1381 }
1382 }
1383 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
1384 print $formfile->showPreview($file_list, $fichinter_static->element, $relativepath, 0);
1385 }
1386 print '</td><td class="left">';
1387 if ($fichinter_static->fk_project > 0) {
1388 $project->fetch($fichinter_static->fk_project);
1389 print $project->getNomUrl(1);
1390 }
1391 // $filename = dol_sanitizeFileName($objp->ref);
1392 // $filedir = getMultidirOutput($fichinter_static).'/'.dol_sanitizeFileName($objp->ref);
1393 // $urlsource = '/fichinter/card.php?id='.$objp->cid;
1394 // print $formfile->getDocumentsLink($fichinter_static->element, $filename, $filedir);
1395 print '</td>'."\n";
1396 //print '<td class="right" width="80px">'.dol_print_date($db->jdate($objp->startdate)).'</td>'."\n";
1397 print '<td class="right" style="min-width: 60px">'.convertSecondToTime($objp->duration).'</td>'."\n";
1398 print '<td class="nowrap right" style="min-width: 60px">'.$fichinter_static->getLibStatut(5).'</td>'."\n";
1399 print '</tr>';
1400
1401 $i++;
1402 }
1403 $db->free($resql);
1404
1405 if ($num > 0) {
1406 print "</table>";
1407 print '</div>';
1408 }
1409 } else {
1410 dol_print_error($db);
1411 }
1412 }
1413
1414 /*
1415 * Latest invoices templates
1416 */
1417 if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
1418 $sql = 'SELECT f.rowid as id, f.titre as ref, f.fk_projet';
1419 $sql .= ', f.total_ht';
1420 $sql .= ', f.total_tva';
1421 $sql .= ', f.total_ttc';
1422 $sql .= ', f.datec as dc';
1423 $sql .= ', f.date_last_gen, f.date_when';
1424 $sql .= ', f.frequency';
1425 $sql .= ', f.unit_frequency';
1426 $sql .= ', f.suspended as suspended';
1427 $sql .= ', s.nom, s.rowid as socid';
1428 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f";
1429 $sql .= " WHERE f.fk_soc = s.rowid AND s.rowid = ".((int) $object->id);
1430 $sql .= " AND f.entity IN (".getEntity('invoice').")";
1431 $sql .= ' GROUP BY f.rowid, f.titre, f.fk_projet, f.total_ht, f.total_tva, f.total_ttc,';
1432 $sql .= ' f.date_last_gen, f.datec, f.frequency, f.unit_frequency,';
1433 $sql .= ' f.suspended, f.date_when,';
1434 $sql .= ' s.nom, s.rowid';
1435 $sql .= " ORDER BY f.date_last_gen, f.datec DESC";
1436
1437 $resql = $db->query($sql);
1438 if ($resql) {
1439 $invoicetemplate = new FactureRec($db);
1440
1441 $num = $db->num_rows($resql);
1442 if ($num > 0) {
1443 print '<div class="div-table-responsive-no-min">';
1444 print '<table class="noborder centpercent lastrecordtable">';
1445 print '<tr class="liste_titre">';
1446 $colspan = 5;
1447 if (getDolGlobalString('MAIN_SHOW_PRICE_WITH_TAX_IN_SUMMARIES')) {
1448 $colspan++;
1449 }
1450 print '<td colspan="'.$colspan.'">';
1451 print '<table class="centpercent nobordernopadding"><tr>';
1452 print '<td>'.$langs->trans("LatestCustomerTemplateInvoices", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/compta/facture/invoicetemplate_list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllCustomerTemplateInvoices").'</span><span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
1453 print '</tr></table>';
1454 print '</td>';
1455 print '</tr>';
1456 }
1457
1458 $i = 0;
1459 while ($i < $num && $i < $MAXLIST) {
1460 $objp = $db->fetch_object($resql);
1461
1462 $invoicetemplate->id = $objp->id;
1463 $invoicetemplate->ref = $objp->ref;
1464 $invoicetemplate->fk_project = $objp->fk_projet;
1465 $invoicetemplate->suspended = $objp->suspended;
1466 $invoicetemplate->frequency = $objp->frequency;
1467 $invoicetemplate->unit_frequency = $objp->unit_frequency;
1468 $invoicetemplate->total_ht = $objp->total_ht;
1469 $invoicetemplate->total_tva = $objp->total_tva;
1470 $invoicetemplate->total_ttc = $objp->total_ttc;
1471 $invoicetemplate->date_last_gen = $objp->date_last_gen;
1472 $invoicetemplate->date_when = $objp->date_when;
1473
1474 print '<tr class="oddeven">';
1475 print '<td class="tdoverflowmax250">';
1476 print $invoicetemplate->getNomUrl(1);
1477 print '</td><td class="left">';
1478 if ($invoicetemplate->fk_project > 0) {
1479 $project->fetch($invoicetemplate->fk_project);
1480 print $project->getNomUrl(1);
1481 }
1482 print '</td>';
1483
1484 if ($objp->frequency && $objp->date_last_gen > 0) {
1485 print '<td class="right" width="80px">'.dol_print_date($db->jdate($objp->date_last_gen), 'day').'</td>';
1486 } else {
1487 if ($objp->dc > 0) {
1488 print '<td class="right" width="80px">'.dol_print_date($db->jdate($objp->dc), 'day').'</td>';
1489 } else {
1490 print '<td class="right"><b>!!!</b></td>';
1491 }
1492 }
1493 print '<td class="right nowraponall">';
1494 print price($objp->total_ht);
1495 print '</td>';
1496
1497 if (getDolGlobalString('MAIN_SHOW_PRICE_WITH_TAX_IN_SUMMARIES')) {
1498 print '<td class="right nowraponall">';
1499 print price($objp->total_ttc);
1500 print '</td>';
1501 }
1502
1503 print '<td class="nowrap right" style="min-width: 60px">';
1504 print $langs->trans('FrequencyPer_'.$invoicetemplate->unit_frequency, $invoicetemplate->frequency).' - ';
1505 print($invoicetemplate->LibStatut($invoicetemplate->frequency, $invoicetemplate->suspended, 5, 0));
1506 print '</td>';
1507 print "</tr>\n";
1508 $i++;
1509 }
1510 $db->free($resql);
1511
1512 if ($num > 0) {
1513 print "</table>";
1514 print '</div>';
1515 }
1516 } else {
1517 dol_print_error($db);
1518 }
1519 }
1520
1521 /*
1522 * Latest invoices
1523 */
1524 if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
1525 $sql = 'SELECT f.rowid as facid, f.ref, f.type, f.ref_client, f.fk_projet';
1526 $sql .= ', f.total_ht';
1527 $sql .= ', f.total_tva';
1528 $sql .= ', f.total_ttc';
1529 $sql .= ', f.entity';
1530 $sql .= ', f.datef as df, f.date_lim_reglement as dl, f.datec as dc, f.paye as paye, f.fk_statut as status';
1531 $sql .= ', s.nom, s.rowid as socid';
1532 $sql .= ', SUM(pf.amount) as am';
1533 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f";
1534 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture as pf ON f.rowid=pf.fk_facture';
1535 $sql .= " WHERE f.fk_soc = s.rowid AND s.rowid = ".((int) $object->id);
1536 $sql .= " AND f.entity IN (".getEntity('invoice').")";
1537 $sql .= ' GROUP BY f.rowid, f.ref, f.type, f.ref_client, f.fk_projet, f.total_ht, f.total_tva, f.total_ttc,';
1538 $sql .= ' f.entity, f.datef, f.date_lim_reglement, f.datec, f.paye, f.fk_statut,';
1539 $sql .= ' s.nom, s.rowid';
1540 $sql .= " ORDER BY f.datef DESC, f.datec DESC";
1541
1542 $resql = $db->query($sql);
1543 if ($resql) {
1544 $facturestatic = new Facture($db);
1545
1546 $num = $db->num_rows($resql);
1547 if ($num > 0) {
1548 print '<div class="div-table-responsive-no-min">';
1549 print '<table class="noborder centpercent lastrecordtable">';
1550 print '<tr class="liste_titre">';
1551 $colspan = 6;
1552 if (getDolGlobalString('MAIN_SHOW_PRICE_WITH_TAX_IN_SUMMARIES')) {
1553 $colspan++;
1554 }
1555 if (getDolGlobalString('MAIN_SHOW_REF_CUSTOMER_INVOICES')) {
1556 $colspan++;
1557 }
1558 print '<td colspan="'.$colspan.'">';
1559 print '<table class="centpercent nobordernopadding"><tr><td>'.$langs->trans("LastCustomersBills", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->id.'"><span class="hideonsmartphone">'.$langs->trans("AllBills").'</span><span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
1560 print '<td width="20px" class="right"><a href="'.DOL_URL_ROOT.'/compta/facture/stats/index.php?socid='.$object->id.'">'.img_picto($langs->trans("Statistics"), 'stats').'</a></td>';
1561 print '</tr></table>';
1562 print '</td>';
1563 print '</tr>';
1564 }
1565
1566 $i = 0;
1567 while ($i < $num && $i < $MAXLIST) {
1568 $objp = $db->fetch_object($resql);
1569
1570 $facturestatic->id = $objp->facid;
1571 $facturestatic->ref = $objp->ref;
1572 $facturestatic->ref_client = $objp->ref_client;
1573 $facturestatic->fk_project = $objp->fk_projet;
1574 $facturestatic->type = $objp->type;
1575 $facturestatic->total_ht = $objp->total_ht;
1576 $facturestatic->total_tva = $objp->total_tva;
1577 $facturestatic->total_ttc = $objp->total_ttc;
1578 $facturestatic->statut = $objp->status;
1579 $facturestatic->status = $objp->status;
1580 $facturestatic->paye = $objp->paye;
1581 $facturestatic->alreadypaid = $objp->am;
1582 $facturestatic->totalpaid = $objp->am;
1583 $facturestatic->date = $db->jdate($objp->df);
1584 $facturestatic->date_lim_reglement = $db->jdate($objp->dl);
1585
1586 print '<tr class="oddeven">';
1587 print '<td class="nowraponall">';
1588 print $facturestatic->getNomUrl(1);
1589 // Preview
1590 $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1591 $file_list = null;
1592 if (!empty($filedir)) {
1593 $file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
1594 }
1595 if (is_array($file_list) && !empty($file_list)) {
1596 // Defined relative dir to DOL_DATA_ROOT
1597 $relativedir = '';
1598 if ($filedir) {
1599 $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir);
1600 $relativedir = preg_replace('/^[\\/]/', '', $relativedir);
1601 }
1602 // Get list of files stored into database for same relative directory
1603 if ($relativedir) {
1604 completeFileArrayWithDatabaseInfo($file_list, $relativedir);
1605 '@phan-var-force array<array{name:string,path:string,level1name:string,relativename:string,fullname:string,date:string,size:int,perm:int,type:string,position_name:string,cover:string,keywords:string,acl:string,rowid:int,label:string,share:string}> $file_list';
1606
1607 //var_dump($sortfield.' - '.$sortorder);
1608 if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1609 $file_list = dol_sort_array($file_list, $sortfield, $sortorder);
1610 }
1611 }
1612 $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf';
1613 print $formfile->showPreview($file_list, $facturestatic->element, $relativepath, 0);
1614 }
1615 print '</td><td class="left">';
1616 if ($facturestatic->fk_project > 0) {
1617 $project->fetch($facturestatic->fk_project);
1618 print $project->getNomUrl(1);
1619 }
1620 // $filename = dol_sanitizeFileName($objp->ref);
1621 // $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
1622 // $urlsource = '/compta/facture/card.php?id='.$objp->cid;
1623 //print $formfile->getDocumentsLink($facturestatic->element, $filename, $filedir);
1624 print '</td>';
1625 if (getDolGlobalString('MAIN_SHOW_REF_CUSTOMER_INVOICES')) {
1626 print '<td class="left nowraponall">';
1627 print $objp->ref_client;
1628 print '</td>';
1629 }
1630 if ($objp->df > 0) {
1631 print '<td width="80px" title="'.dol_escape_htmltag($langs->trans('DateInvoice')).'">'.dol_print_date($db->jdate($objp->df), 'day').'</td>';
1632 } else {
1633 print '<td><b>!!!</b></td>';
1634 }
1635 if ($objp->dl > 0) {
1636 print '<td width="80px" title="'.dol_escape_htmltag($langs->trans('DateMaxPayment')).'">'.dol_print_date($db->jdate($objp->dl), 'day').'</td>';
1637 } else {
1638 print '<td><b>!!!</b></td>';
1639 }
1640
1641 print '<td class="right nowraponall">';
1642 print price($objp->total_ht);
1643 print '</td>';
1644
1645 if (getDolGlobalString('MAIN_SHOW_PRICE_WITH_TAX_IN_SUMMARIES')) {
1646 print '<td class="right nowraponall">';
1647 print price($objp->total_ttc);
1648 print '</td>';
1649 }
1650
1651 print '<td class="nowrap right" style="min-width: 60px">'.($facturestatic->LibStatut($objp->paye, $objp->status, 5, $objp->am)).'</td>';
1652 print "</tr>\n";
1653 $i++;
1654 }
1655 $db->free($resql);
1656
1657 if ($num > 0) {
1658 print "</table>";
1659 print '</div>';
1660 }
1661 } else {
1662 dol_print_error($db);
1663 }
1664 }
1665
1666 // Allow external modules to add their own shortlist of recent objects
1667 $parameters = array();
1668 $reshook = $hookmanager->executeHooks('addMoreRecentObjects', $parameters, $object, $action);
1669 if ($reshook < 0) {
1670 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1671 } else {
1672 print $hookmanager->resPrint;
1673 }
1674
1675 print '</div></div>';
1676 print '<div class="clearboth"></div>';
1677
1678 print dol_get_fiche_end();
1679
1680
1681 /*
1682 * Action bar
1683 */
1684 print '<div class="tabsAction">';
1685
1686 $parameters = array();
1687 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1688
1689 if (empty($reshook)) {
1690 if ($object->status != 1) {
1691 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyIsClosed")).'" href="#">'.$langs->trans("ThirdPartyIsClosed").'</a></div>';
1692 }
1693
1694 if (isModEnabled("propal") && $user->hasRight('propal', 'creer') && $object->status == 1) {
1695 $langs->load("propal");
1696 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/propal/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddProp").'</a></div>';
1697 }
1698
1699 if (isModEnabled('order') && $user->hasRight('commande', 'creer') && $object->status == 1) {
1700 $langs->load("orders");
1701 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddOrder").'</a></div>';
1702 }
1703
1704 if ($user->hasRight('contrat', 'creer') && $object->status == 1) {
1705 $langs->load("contracts");
1706 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/contrat/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddContract").'</a></div>';
1707 }
1708
1709 if (isModEnabled('intervention') && $user->hasRight('ficheinter', 'creer') && $object->status == 1) {
1710 $langs->load("interventions");
1711 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fichinter/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddIntervention").'</a></div>';
1712 }
1713
1714 // Add invoice
1715 if ($user->socid == 0) {
1716 if (isModEnabled('deplacement') && $object->status == 1) {
1717 $langs->load("trips");
1718 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/deplacement/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddTrip").'</a></div>';
1719 }
1720
1721 if (isModEnabled('invoice') && $object->status == 1) {
1722 if (!$user->hasRight('facture', 'creer')) {
1723 $langs->load("bills");
1724 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NotAllowed")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
1725 } else {
1726 $langs->loadLangs(array("orders", "bills"));
1727
1728 if (isModEnabled('order')) {
1729 if ($object->client != 0 && $object->client != 2) {
1730 if (!empty($orders2invoice) && $orders2invoice > 0) {
1731 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->id.'&search_billed=0&autoselectall=1">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
1732 } else {
1733 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NoOrdersToInvoice")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
1734 }
1735 } else {
1736 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
1737 }
1738 }
1739
1740 if ($object->client != 0 && $object->client != 2) {
1741 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&socid='.$object->id.'">'.$langs->trans("AddBill").'</a></div>';
1742 } else {
1743 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
1744 }
1745 }
1746 }
1747 }
1748
1749 // Add action
1750 if (isModEnabled('agenda') && getDolGlobalString('MAIN_REPEATTASKONEACHTAB') && $object->status == 1) {
1751 if ($user->hasRight('agenda', 'myactions', 'create')) {
1752 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&socid='.$object->id.'">'.$langs->trans("AddAction").'</a></div>';
1753 } else {
1754 print '<div class="inline-block divButAction"><a class="butAction" title="'.dol_escape_js($langs->trans("NotAllowed")).'" href="#">'.$langs->trans("AddAction").'</a></div>';
1755 }
1756 }
1757 }
1758
1759 print '</div>';
1760
1761 if (getDolGlobalString('MAIN_DUPLICATE_CONTACTS_TAB_ON_CUSTOMER_CARD')) {
1762 // List of contacts
1763 show_contacts($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?socid='.$object->id);
1764 }
1765
1766 if (getDolGlobalString('MAIN_REPEATTASKONEACHTAB')) {
1767 print load_fiche_titre($langs->trans("ActionsOnCompany"), '', '');
1768
1769 // List of todo actions
1770 show_actions_todo($conf, $langs, $db, $object);
1771
1772 // List of done actions
1773 show_actions_done($conf, $langs, $db, $object);
1774 }
1775} else {
1776 $langs->load("errors");
1777 print $langs->trans('ErrorRecordNotFound');
1778}
1779
1780// End of page
1781llxFooter();
1782$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
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 accounting accounts.
Class to manage members of a foundation.
Class to manage customers or prospects.
Class to manage customers orders.
Class to manage contact/addresses.
Class to manage standard extra fields.
Class to manage invoices.
Class to manage invoice templates.
Class to manage generation of HTML components for accounting management.
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 with static methods for building HTML components related to products Only components common to ...
Class to manage projects.
Class to manage proposals.
Class to manage Dolibarr users.
show_contacts($conf, $langs, $db, $object, $backtopage='', $showuserlogin=0)
Show html area for list of contacts.
show_actions_done($conf, $langs, $db, $filterobj, $objcon=null, $noprint=0, $actioncode='', $donetodo='done', $filters=array(), $sortfield='a.datep, a.id', $sortorder='DESC', $module='')
Show html area with actions (done or not, ignore the name of function).
societe_prepare_head(Societe $object)
Return array of tabs to used on pages for third parties cards.
show_actions_todo($conf, $langs, $db, $filterobj, $objcon=null, $noprint=0, $actioncode='')
Show html area with actions to do.
llxFooter()
Footer empty.
Definition document.php:107
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
Complete $filearray with data from database.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
img_action($titlealt, $numaction, $picto='', $moreatt='')
Show logo action.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
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...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
yn($yesno, $format=1, $color=0)
Return yes or no in current language.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.