element.php 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692
  1. <?php
  2. /* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2012-2016 Juanjo Menent <jmenent@2byte.es>
  6. * Copyright (C) 2015-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
  7. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  8. * Copyright (C) 2016 Josep Lluís Amador <joseplluis@lliuretic.cat>
  9. * Copyright (C) 2021-2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
  10. * Copyright (C) 2021 Noé Cendrier <noe.cendrier@altairis.fr>
  11. * Copyright (C) 2023 Frédéric France wfrederic.france@netlogic.fr>
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  24. */
  25. /**
  26. * \file htdocs/projet/element.php
  27. * \ingroup projet
  28. * \brief Page of project referrers
  29. */
  30. // Load Dolibarr environment
  31. require '../main.inc.php';
  32. require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
  33. require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
  34. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
  35. require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
  36. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  37. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
  38. if (isModEnabled('agenda')) {
  39. require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
  40. }
  41. if (isModEnabled('banque')) {
  42. require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
  43. }
  44. if (isModEnabled('categorie')) {
  45. require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
  46. }
  47. if (isModEnabled('commande')) {
  48. require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
  49. }
  50. if (isModEnabled('contrat')) {
  51. require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
  52. }
  53. if (isModEnabled('deplacement')) {
  54. require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
  55. }
  56. if (isModEnabled('don')) {
  57. require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
  58. }
  59. if (isModEnabled('expedition')) {
  60. require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
  61. }
  62. if (isModEnabled('expensereport')) {
  63. require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
  64. }
  65. if (isModEnabled('facture')) {
  66. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  67. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
  68. }
  69. if (isModEnabled('ficheinter')) {
  70. require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
  71. }
  72. if (isModEnabled('loan')) {
  73. require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
  74. require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
  75. }
  76. if (isModEnabled('mrp')) {
  77. require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
  78. }
  79. if (isModEnabled('propal')) {
  80. require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
  81. }
  82. if (isModEnabled('salaries')) {
  83. require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
  84. }
  85. if (isModEnabled('stock')) {
  86. require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
  87. require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
  88. }
  89. if (isModEnabled('supplier_invoice')) {
  90. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  91. }
  92. if (isModEnabled('supplier_order')) {
  93. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
  94. }
  95. if (isModEnabled('supplier_proposal')) {
  96. require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
  97. }
  98. if (isModEnabled('tax')) {
  99. require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
  100. }
  101. if (isModEnabled('stocktransfer')) {
  102. require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php';
  103. require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransferline.class.php';
  104. }
  105. // Load translation files required by the page
  106. $langs->loadLangs(array('projects', 'companies', 'suppliers', 'compta'));
  107. if (isModEnabled('facture')) {
  108. $langs->load("bills");
  109. }
  110. if (isModEnabled('commande')) {
  111. $langs->load("orders");
  112. }
  113. if (isModEnabled("propal")) {
  114. $langs->load("propal");
  115. }
  116. if (isModEnabled('ficheinter')) {
  117. $langs->load("interventions");
  118. }
  119. if (isModEnabled('deplacement')) {
  120. $langs->load("trips");
  121. }
  122. if (isModEnabled('expensereport')) {
  123. $langs->load("trips");
  124. }
  125. if (isModEnabled('don')) {
  126. $langs->load("donations");
  127. }
  128. if (isModEnabled('loan')) {
  129. $langs->load("loan");
  130. }
  131. if (isModEnabled('salaries')) {
  132. $langs->load("salaries");
  133. }
  134. if (isModEnabled('mrp')) {
  135. $langs->load("mrp");
  136. }
  137. if (isModEnabled('eventorganization')) {
  138. $langs->load("eventorganization");
  139. }
  140. //if (isModEnabled('stocktransfer')) {
  141. // $langs->load("stockstransfer");
  142. //}
  143. $id = GETPOST('id', 'int');
  144. $ref = GETPOST('ref', 'alpha');
  145. $action = GETPOST('action', 'aZ09');
  146. $datesrfc = GETPOST('datesrfc');
  147. $dateerfc = GETPOST('dateerfc');
  148. $dates = dol_mktime(0, 0, 0, GETPOST('datesmonth'), GETPOST('datesday'), GETPOST('datesyear'));
  149. $datee = dol_mktime(23, 59, 59, GETPOST('dateemonth'), GETPOST('dateeday'), GETPOST('dateeyear'));
  150. if (empty($dates) && !empty($datesrfc)) {
  151. $dates = dol_stringtotime($datesrfc);
  152. }
  153. if (empty($datee) && !empty($dateerfc)) {
  154. $datee = dol_stringtotime($dateerfc);
  155. }
  156. if (!GETPOSTISSET('datesrfc') && !GETPOSTISSET('datesday') && getDolGlobalString('PROJECT_LINKED_ELEMENT_DEFAULT_FILTER_YEAR')) {
  157. $new = dol_now();
  158. $tmp = dol_getdate($new);
  159. //$datee=$now
  160. //$dates=dol_time_plus_duree($datee, -1, 'y');
  161. $dates = dol_get_first_day($tmp['year'], 1);
  162. }
  163. if ($id == '' && $ref == '') {
  164. setEventMessage($langs->trans('ErrorBadParameters'), 'errors');
  165. header('Location: list.php');
  166. exit();
  167. }
  168. $mine = GETPOST('mode') == 'mine' ? 1 : 0;
  169. //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
  170. $object = new Project($db);
  171. include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
  172. if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
  173. $object->fetchComments();
  174. }
  175. // Security check
  176. $socid = $object->socid;
  177. //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement.
  178. $result = restrictedArea($user, 'projet', $object->id, 'projet&project');
  179. $hookmanager->initHooks(array('projectOverview'));
  180. /*
  181. * View
  182. */
  183. $title = $langs->trans('ProjectReferers').' - '.$object->ref.' '.$object->name;
  184. if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
  185. $title = $object->ref.' '.$object->name.' - '.$langs->trans('ProjectReferers');
  186. }
  187. $help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
  188. llxHeader('', $title, $help_url);
  189. $form = new Form($db);
  190. $formproject = new FormProjets($db);
  191. $formfile = new FormFile($db);
  192. $userstatic = new User($db);
  193. // To verify role of users
  194. $userAccess = $object->restrictedProjectArea($user);
  195. $head = project_prepare_head($object);
  196. print dol_get_fiche_head($head, 'element', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
  197. // Project card
  198. if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
  199. $tmpurl = $_SESSION['pageforbacktolist']['project'];
  200. $tmpurl = preg_replace('/__SOCID__/', $object->socid, $tmpurl);
  201. $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
  202. } else {
  203. $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
  204. }
  205. $morehtmlref = '<div class="refidno">';
  206. // Title
  207. $morehtmlref .= $object->title;
  208. // Thirdparty
  209. if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
  210. $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
  211. }
  212. $morehtmlref .= '</div>';
  213. // Define a complementary filter for search of next/prev ref.
  214. if (!$user->hasRight('projet', 'all', 'lire')) {
  215. $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
  216. $object->next_prev_filter = "te.rowid IN (".$db->sanitize(count($objectsListId) ? join(',', array_keys($objectsListId)) : '0').")";
  217. }
  218. dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
  219. print '<div class="fichecenter">';
  220. print '<div class="fichehalfleft">';
  221. print '<div class="underbanner clearboth"></div>';
  222. print '<table class="border tableforfield centpercent">';
  223. // Usage
  224. if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
  225. print '<tr><td class="tdtop">';
  226. print $langs->trans("Usage");
  227. print '</td>';
  228. print '<td>';
  229. if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
  230. print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
  231. $htmltext = $langs->trans("ProjectFollowOpportunity");
  232. print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
  233. print '<br>';
  234. }
  235. if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
  236. print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
  237. $htmltext = $langs->trans("ProjectFollowTasks");
  238. print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
  239. print '<br>';
  240. }
  241. if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
  242. print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')).'"> ';
  243. $htmltext = $langs->trans("ProjectBillTimeDescription");
  244. print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
  245. print '<br>';
  246. }
  247. if (isModEnabled('eventorganization')) {
  248. print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')).'"> ';
  249. $htmltext = $langs->trans("EventOrganizationDescriptionLong");
  250. print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
  251. }
  252. print '</td></tr>';
  253. }
  254. // Visibility
  255. print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
  256. if ($object->public) {
  257. print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
  258. print $langs->trans('SharedProject');
  259. } else {
  260. print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
  261. print $langs->trans('PrivateProject');
  262. }
  263. print '</td></tr>';
  264. if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
  265. // Opportunity status
  266. print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
  267. $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
  268. if ($code) {
  269. print $langs->trans("OppStatus".$code);
  270. }
  271. print '</td></tr>';
  272. // Opportunity percent
  273. print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>';
  274. if (!is_null($object->opp_percent) && strcmp($object->opp_percent, '')) {
  275. print price($object->opp_percent, '', $langs, 1, 0).' %';
  276. }
  277. print '</td></tr>';
  278. // Opportunity Amount
  279. print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
  280. if (!is_null($object->opp_amount) && strcmp($object->opp_amount, '')) {
  281. print '<span class="amount">'.price($object->opp_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
  282. if (strcmp($object->opp_percent, '')) {
  283. print ' &nbsp; &nbsp; &nbsp; <span title="'.dol_escape_htmltag($langs->trans('OpportunityWeightedAmount')).'"><span class="opacitymedium">'.$langs->trans("Weighted").'</span>: <span class="amount">'.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).'</span></span>';
  284. }
  285. }
  286. print '</td></tr>';
  287. }
  288. // Budget
  289. print '<tr><td>'.$langs->trans("Budget").'</td><td>';
  290. if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
  291. print '<span class="amount">'.price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
  292. }
  293. print '</td></tr>';
  294. // Date start - end project
  295. print '<tr><td>'.$langs->trans("Dates").'</td><td>';
  296. $start = dol_print_date($object->date_start, 'day');
  297. print($start ? $start : '?');
  298. $end = dol_print_date($object->date_end, 'day');
  299. print ' - ';
  300. print($end ? $end : '?');
  301. if ($object->hasDelay()) {
  302. print img_warning("Late");
  303. }
  304. print '</td></tr>';
  305. // Other attributes
  306. $cols = 2;
  307. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
  308. print '</table>';
  309. print '</div>';
  310. print '<div class="fichehalfright">';
  311. print '<div class="underbanner clearboth"></div>';
  312. print '<table class="border tableforfield centpercent">';
  313. // Description
  314. print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
  315. print dol_htmlentitiesbr($object->description);
  316. print '</td></tr>';
  317. // Categories
  318. if (isModEnabled('categorie')) {
  319. print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
  320. print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
  321. print "</td></tr>";
  322. }
  323. print '</table>';
  324. print '</div>';
  325. print '</div>';
  326. print '<div class="clearboth"></div>';
  327. print dol_get_fiche_end();
  328. print '<br>';
  329. /*
  330. * Referers types
  331. */
  332. $listofreferent = array(
  333. 'entrepot'=>array(
  334. 'name'=>"Warehouse",
  335. 'title'=>"ListWarehouseAssociatedProject",
  336. 'class'=>'Entrepot',
  337. 'table'=>'entrepot',
  338. 'datefieldname'=>'date_entrepot',
  339. 'urlnew'=>DOL_URL_ROOT.'/product/stock/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  340. 'lang'=>'entrepot',
  341. 'buttonnew'=>'AddWarehouse',
  342. 'project_field'=>'fk_project',
  343. 'testnew'=>$user->hasRight('stock', 'creer'),
  344. 'test'=>isModEnabled('stock') && $user->hasRight('stock', 'lire') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROJECT')
  345. ),
  346. 'propal'=>array(
  347. 'name'=>"Proposals",
  348. 'title'=>"ListProposalsAssociatedProject",
  349. 'class'=>'Propal',
  350. 'table'=>'propal',
  351. 'datefieldname'=>'datep',
  352. 'urlnew'=>DOL_URL_ROOT.'/comm/propal/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  353. 'lang'=>'propal',
  354. 'buttonnew'=>'AddProp',
  355. 'testnew'=>$user->hasRight('propal', 'creer'),
  356. 'test'=>isModEnabled('propal') && $user->hasRight('propal', 'lire')
  357. ),
  358. 'order'=>array(
  359. 'name'=>"CustomersOrders",
  360. 'title'=>"ListOrdersAssociatedProject",
  361. 'class'=>'Commande',
  362. 'table'=>'commande',
  363. 'datefieldname'=>'date_commande',
  364. 'urlnew'=>DOL_URL_ROOT.'/commande/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  365. 'lang'=>'orders',
  366. 'buttonnew'=>'CreateOrder',
  367. 'testnew'=>$user->hasRight('commande', 'creer'),
  368. 'test'=>isModEnabled('commande') && $user->hasRight('commande', 'lire')
  369. ),
  370. 'invoice'=>array(
  371. 'name'=>"CustomersInvoices",
  372. 'title'=>"ListInvoicesAssociatedProject",
  373. 'class'=>'Facture',
  374. 'margin'=>'add',
  375. 'table'=>'facture',
  376. 'datefieldname'=>'datef',
  377. 'urlnew'=>DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  378. 'lang'=>'bills',
  379. 'buttonnew'=>'CreateBill',
  380. 'testnew'=>$user->hasRight('facture', 'creer'),
  381. 'test'=>isModEnabled('facture') && $user->hasRight('facture', 'lire')
  382. ),
  383. 'invoice_predefined'=>array(
  384. 'name'=>"PredefinedInvoices",
  385. 'title'=>"ListPredefinedInvoicesAssociatedProject",
  386. 'class'=>'FactureRec',
  387. 'table'=>'facture_rec',
  388. 'datefieldname'=>'datec',
  389. 'urlnew'=>DOL_URL_ROOT.'/compta/facture/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  390. 'lang'=>'bills',
  391. 'buttonnew'=>'CreateBill',
  392. 'testnew'=>$user->hasRight('facture', 'creer'),
  393. 'test'=>isModEnabled('facture') && $user->hasRight('facture', 'lire')
  394. ),
  395. 'proposal_supplier'=>array(
  396. 'name'=>"SupplierProposals",
  397. 'title'=>"ListSupplierProposalsAssociatedProject",
  398. 'class'=>'SupplierProposal',
  399. 'table'=>'supplier_proposal',
  400. 'datefieldname'=>'date_valid',
  401. 'urlnew'=>DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
  402. 'lang'=>'supplier_proposal',
  403. 'buttonnew'=>'AddSupplierProposal',
  404. 'testnew'=>$user->hasRight('supplier_proposal', 'creer'),
  405. 'test'=>isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')
  406. ),
  407. 'order_supplier'=>array(
  408. 'name'=>"SuppliersOrders",
  409. 'title'=>"ListSupplierOrdersAssociatedProject",
  410. 'class'=>'CommandeFournisseur',
  411. 'table'=>'commande_fournisseur',
  412. 'datefieldname'=>'date_commande',
  413. 'urlnew'=>DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
  414. 'lang'=>'suppliers',
  415. 'buttonnew'=>'AddSupplierOrder',
  416. 'testnew'=>$user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'),
  417. 'test'=>isModEnabled('supplier_order') && $user->hasRight('fournisseur', 'commande', 'lire') || $user->hasRight('supplier_order', 'lire')
  418. ),
  419. 'invoice_supplier'=>array(
  420. 'name'=>"BillsSuppliers",
  421. 'title'=>"ListSupplierInvoicesAssociatedProject",
  422. 'class'=>'FactureFournisseur',
  423. 'margin'=>'minus',
  424. 'table'=>'facture_fourn',
  425. 'datefieldname'=>'datef',
  426. 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), // No socid parameter here, the socid is often the customer and we create a supplier object
  427. 'lang'=>'suppliers',
  428. 'buttonnew'=>'AddSupplierInvoice',
  429. 'testnew'=>$user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer'),
  430. 'test'=>isModEnabled('supplier_invoice') && $user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'lire')
  431. ),
  432. 'contract'=>array(
  433. 'name'=>"Contracts",
  434. 'title'=>"ListContractAssociatedProject",
  435. 'class'=>'Contrat',
  436. 'table'=>'contrat',
  437. 'datefieldname'=>'date_contrat',
  438. 'urlnew'=>DOL_URL_ROOT.'/contrat/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  439. 'lang'=>'contracts',
  440. 'buttonnew'=>'AddContract',
  441. 'testnew'=>$user->hasRight('contrat', 'creer'),
  442. 'test'=>isModEnabled('contrat') && $user->hasRight('contrat', 'lire')
  443. ),
  444. 'intervention'=>array(
  445. 'name'=>"Interventions",
  446. 'title'=>"ListFichinterAssociatedProject",
  447. 'class'=>'Fichinter',
  448. 'table'=>'fichinter',
  449. 'datefieldname'=>'date_valid',
  450. 'disableamount'=>0,
  451. 'margin'=>'',
  452. 'urlnew'=>DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  453. 'lang'=>'interventions',
  454. 'buttonnew'=>'AddIntervention',
  455. 'testnew'=>$user->hasRight('ficheinter', 'creer'),
  456. 'test'=>isModEnabled('ficheinter') && $user->hasRight('ficheinter', 'lire')
  457. ),
  458. 'shipping'=>array(
  459. 'name'=>"Shippings",
  460. 'title'=>"ListShippingAssociatedProject",
  461. 'class'=>'Expedition',
  462. 'table'=>'expedition',
  463. 'datefieldname'=>'date_valid',
  464. 'urlnew'=>DOL_URL_ROOT.'/expedition/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  465. 'lang'=>'sendings',
  466. 'buttonnew'=>'CreateShipment',
  467. 'testnew'=>0,
  468. 'test'=>isModEnabled('expedition') && $user->hasRight('expedition', 'lire')
  469. ),
  470. 'mrp'=>array(
  471. 'name'=>"MO",
  472. 'title'=>"ListMOAssociatedProject",
  473. 'class'=>'Mo',
  474. 'table'=>'mrp_mo',
  475. 'datefieldname'=>'date_valid',
  476. 'urlnew'=>DOL_URL_ROOT.'/mrp/mo_card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  477. 'lang'=>'mrp',
  478. 'buttonnew'=>'CreateMO',
  479. 'testnew'=>$user->hasRight('mrp', 'write'),
  480. 'project_field'=>'fk_project',
  481. 'nototal'=>1,
  482. 'test'=>isModEnabled('mrp') && $user->hasRight('mrp', 'read')
  483. ),
  484. 'trip'=>array(
  485. 'name'=>"TripsAndExpenses",
  486. 'title'=>"ListExpenseReportsAssociatedProject",
  487. 'class'=>'Deplacement',
  488. 'table'=>'deplacement',
  489. 'datefieldname'=>'dated',
  490. 'margin'=>'minus',
  491. 'disableamount'=>1,
  492. 'urlnew'=>DOL_URL_ROOT.'/deplacement/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  493. 'lang'=>'trips',
  494. 'buttonnew'=>'AddTrip',
  495. 'testnew'=>$user->hasRight('deplacement', 'creer'),
  496. 'test'=>isModEnabled('deplacement') && $user->hasRight('deplacement', 'lire')
  497. ),
  498. 'expensereport'=>array(
  499. 'name'=>"ExpenseReports",
  500. 'title'=>"ListExpenseReportsAssociatedProject",
  501. 'class'=>'ExpenseReportLine',
  502. 'table'=>'expensereport_det',
  503. 'datefieldname'=>'date',
  504. 'margin'=>'minus',
  505. 'disableamount'=>0,
  506. 'urlnew'=>DOL_URL_ROOT.'/expensereport/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  507. 'lang'=>'trips',
  508. 'buttonnew'=>'AddTrip',
  509. 'testnew'=>$user->hasRight('expensereport', 'creer'),
  510. 'test'=>isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')
  511. ),
  512. 'donation'=>array(
  513. 'name'=>"Donation",
  514. 'title'=>"ListDonationsAssociatedProject",
  515. 'class'=>'Don',
  516. 'margin'=>'add',
  517. 'table'=>'don',
  518. 'datefieldname'=>'datedon',
  519. 'disableamount'=>0,
  520. 'urlnew'=>DOL_URL_ROOT.'/don/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  521. 'lang'=>'donations',
  522. 'buttonnew'=>'AddDonation',
  523. 'testnew'=>$user->hasRight('don', 'creer'),
  524. 'test'=>isModEnabled('don') && $user->hasRight('don', 'lire')
  525. ),
  526. 'loan'=>array(
  527. 'name'=>"Loan",
  528. 'title'=>"ListLoanAssociatedProject",
  529. 'class'=>'Loan',
  530. 'margin'=>'add',
  531. 'table'=>'loan',
  532. 'datefieldname'=>'datestart',
  533. 'disableamount'=>0,
  534. 'urlnew'=>DOL_URL_ROOT.'/loan/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  535. 'lang'=>'loan',
  536. 'buttonnew'=>'AddLoan',
  537. 'testnew'=>$user->hasRight('loan', 'write'),
  538. 'test'=>isModEnabled('loan') && $user->hasRight('loan', 'read')
  539. ),
  540. 'chargesociales'=>array(
  541. 'name'=>"SocialContribution",
  542. 'title'=>"ListSocialContributionAssociatedProject",
  543. 'class'=>'ChargeSociales',
  544. 'margin'=>'minus',
  545. 'table'=>'chargesociales',
  546. 'datefieldname'=>'date_ech',
  547. 'disableamount'=>0,
  548. 'urlnew'=>DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  549. 'lang'=>'compta',
  550. 'buttonnew'=>'AddSocialContribution',
  551. 'testnew'=>$user->hasRight('tax', 'charges', 'lire'),
  552. 'test'=>isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')
  553. ),
  554. 'project_task'=>array(
  555. 'name'=>"TaskTimeSpent",
  556. 'title'=>"ListTaskTimeUserProject",
  557. 'class'=>'Task',
  558. 'margin'=>'minus',
  559. 'table'=>'projet_task',
  560. 'datefieldname'=>'element_date',
  561. 'disableamount'=>0,
  562. 'urlnew'=>DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  563. 'buttonnew'=>'AddTimeSpent',
  564. 'testnew'=>$user->hasRight('project', 'creer'),
  565. 'test'=>isModEnabled('project') && $user->hasRight('projet', 'lire') && !getDolGlobalString('PROJECT_HIDE_TASKS')
  566. ),
  567. 'stock_mouvement'=>array(
  568. 'name'=>"MouvementStockAssociated",
  569. 'title'=>"ListMouvementStockProject",
  570. 'class'=>'StockTransfer',
  571. 'table'=>'stocktransfer_stocktransfer',
  572. 'datefieldname'=>'datem',
  573. 'margin'=>'minus',
  574. 'project_field'=>'fk_project',
  575. 'disableamount'=>0,
  576. 'test'=>isModEnabled('stock') && $user->hasRight('stock', 'mouvement', 'lire') && getDolGlobalString('STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW')
  577. ),
  578. 'salaries'=>array(
  579. 'name'=>"Salaries",
  580. 'title'=>"ListSalariesAssociatedProject",
  581. 'class'=>'Salary',
  582. 'table'=>'salary',
  583. 'datefieldname'=>'datesp',
  584. 'margin'=>'minus',
  585. 'disableamount'=>0,
  586. 'urlnew'=>DOL_URL_ROOT.'/salaries/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  587. 'lang'=>'salaries',
  588. 'buttonnew'=>'AddSalary',
  589. 'testnew'=>$user->hasRight('salaries', 'write'),
  590. 'test'=>isModEnabled('salaries') && $user->hasRight('salaries', 'read')
  591. ),
  592. 'variouspayment'=>array(
  593. 'name'=>"VariousPayments",
  594. 'title'=>"ListVariousPaymentsAssociatedProject",
  595. 'class'=>'PaymentVarious',
  596. 'table'=>'payment_various',
  597. 'datefieldname'=>'datev',
  598. 'margin'=>'minus',
  599. 'disableamount'=>0,
  600. 'urlnew'=>DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  601. 'lang'=>'banks',
  602. 'buttonnew'=>'AddVariousPayment',
  603. 'testnew'=>$user->hasRight('banque', 'modifier'),
  604. 'test'=>isModEnabled("banque") && $user->hasRight('banque', 'lire') && !getDolGlobalString('BANK_USE_OLD_VARIOUS_PAYMENT')
  605. ),
  606. /* No need for this, available on dedicated tab "Agenda/Events"
  607. 'agenda'=>array(
  608. 'name'=>"Agenda",
  609. 'title'=>"ListActionsAssociatedProject",
  610. 'class'=>'ActionComm',
  611. 'table'=>'actioncomm',
  612. 'datefieldname'=>'datep',
  613. 'disableamount'=>1,
  614. 'urlnew'=>DOL_URL_ROOT.'/comm/action/card.php?action=create&projectid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
  615. 'lang'=>'agenda',
  616. 'buttonnew'=>'AddEvent',
  617. 'testnew'=>$user->rights->agenda->myactions->create,
  618. 'test'=> isModEnabled('agenda') && $user->hasRight('agenda', 'myactions', 'read')),
  619. */
  620. );
  621. // Change rules for profit/benefit calculation
  622. if (getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN')) {
  623. foreach ($listofreferent as $key => $element) {
  624. if ($listofreferent[$key]['margin'] == 'add') {
  625. unset($listofreferent[$key]['margin']);
  626. }
  627. }
  628. $newelementforplusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_PLUS_MARGIN'));
  629. foreach ($newelementforplusmargin as $value) {
  630. $listofreferent[trim($value)]['margin'] = 'add';
  631. }
  632. }
  633. if (getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN')) {
  634. foreach ($listofreferent as $key => $element) {
  635. if ($listofreferent[$key]['margin'] == 'minus') {
  636. unset($listofreferent[$key]['margin']);
  637. }
  638. }
  639. $newelementforminusmargin = explode(',', getDolGlobalString('PROJECT_ELEMENTS_FOR_MINUS_MARGIN'));
  640. foreach ($newelementforminusmargin as $value) {
  641. $listofreferent[trim($value)]['margin'] = 'minus';
  642. }
  643. }
  644. $parameters = array('listofreferent'=>$listofreferent);
  645. $resHook = $hookmanager->executeHooks('completeListOfReferent', $parameters, $object, $action);
  646. if (!empty($hookmanager->resArray)) {
  647. $listofreferent = array_merge($listofreferent, $hookmanager->resArray);
  648. }
  649. if ($action == "addelement") {
  650. $tablename = GETPOST("tablename");
  651. $elementselectid = GETPOST("elementselect");
  652. $result = $object->update_element($tablename, $elementselectid);
  653. if ($result < 0) {
  654. setEventMessages($object->error, $object->errors, 'errors');
  655. }
  656. } elseif ($action == "unlink") {
  657. $tablename = GETPOST("tablename", "aZ09");
  658. $projectField = GETPOSTISSET('projectfield') ? GETPOST('projectfield', 'aZ09') : 'fk_projet';
  659. $elementselectid = GETPOST("elementselect", "int");
  660. $result = $object->remove_element($tablename, $elementselectid, $projectField);
  661. if ($result < 0) {
  662. setEventMessages($object->error, $object->errors, 'errors');
  663. }
  664. }
  665. $elementuser = new User($db);
  666. $showdatefilter = 0;
  667. // Show the filter on date on top of element list
  668. if (!$showdatefilter) {
  669. print '<div class="center centpercent">';
  670. print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
  671. print '<input type="hidden" name="token" value="'.newToken().'">';
  672. print '<input type="hidden" name="tablename" value="'.(empty($tablename) ? '' : $tablename).'">';
  673. print '<input type="hidden" name="action" value="view">';
  674. print '<div class="inline-block">';
  675. print $form->selectDate($dates, 'dates', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
  676. print '</div>';
  677. print '<div class="inline-block">';
  678. print $form->selectDate($datee, 'datee', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
  679. print '</div>';
  680. print '<div class="inline-block">';
  681. print '<input type="submit" name="refresh" value="'.$langs->trans("Refresh").'" class="button small">';
  682. print '</div>';
  683. print '</form>';
  684. print '</div>';
  685. $showdatefilter++;
  686. }
  687. // Show balance for whole project
  688. $langs->loadLangs(array("suppliers", "bills", "orders", "proposals", "margins"));
  689. if (isModEnabled('stock')) {
  690. $langs->load('stocks');
  691. }
  692. print load_fiche_titre($langs->trans("Profit"), '', 'title_accountancy');
  693. print '<table class="noborder centpercent">';
  694. print '<tr class="liste_titre">';
  695. print '<td class="left" width="200">';
  696. $tooltiponprofit = $langs->trans("ProfitIsCalculatedWith")."<br>\n";
  697. $tooltiponprofitplus = $tooltiponprofitminus = '';
  698. foreach ($listofreferent as $key => $value) {
  699. if (!empty($value['lang'])) {
  700. $langs->load($value['lang']);
  701. }
  702. $name = $langs->trans($value['name']);
  703. $qualified = $value['test'];
  704. $margin = empty($value['margin']) ? '' : $value['margin'];
  705. if ($qualified && isset($margin)) { // If this element must be included into profit calculation ($margin is 'minus' or 'add')
  706. if ($margin === 'add') {
  707. $tooltiponprofitplus .= ' &gt; '.$name." (+)<br>\n";
  708. }
  709. if ($margin === 'minus') {
  710. $tooltiponprofitminus .= ' &gt; '.$name." (-)<br>\n";
  711. }
  712. }
  713. }
  714. $tooltiponprofit .= $tooltiponprofitplus;
  715. $tooltiponprofit .= $tooltiponprofitminus;
  716. print $form->textwithpicto($langs->trans("Element"), $tooltiponprofit);
  717. print '</td>';
  718. print '<td class="right" width="100">'.$langs->trans("Number").'</td>';
  719. print '<td class="right" width="100">'.$langs->trans("AmountHT").'</td>';
  720. print '<td class="right" width="100">'.$langs->trans("AmountTTC").'</td>';
  721. print '</tr>';
  722. $total_revenue_ht = 0;
  723. $balance_ht = 0;
  724. $balance_ttc = 0;
  725. // Loop on each element type (proposal, sale order, invoices, ...)
  726. foreach ($listofreferent as $key => $value) {
  727. $parameters = array(
  728. 'total_revenue_ht' =>& $total_revenue_ht,
  729. 'balance_ht' =>& $balance_ht,
  730. 'balance_ttc' =>& $balance_ttc,
  731. 'key' => $key,
  732. 'value' =>& $value,
  733. 'dates' => $dates,
  734. 'datee' => $datee
  735. );
  736. $reshook = $hookmanager->executeHooks('printOverviewProfit', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  737. if ($reshook < 0) {
  738. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  739. } elseif ($reshook > 0) {
  740. print $hookmanager->resPrint;
  741. continue;
  742. }
  743. $name = $langs->trans($value['name']);
  744. $title = $value['title'];
  745. $classname = $value['class'];
  746. $tablename = $value['table'];
  747. $datefieldname = $value['datefieldname'];
  748. $qualified = $value['test'];
  749. $margin = empty($value['margin']) ? 0 : $value['margin'];
  750. $project_field = empty($value['project_field']) ? '' : $value['project_field'];
  751. if ($qualified && isset($margin)) { // If this element must be included into profit calculation ($margin is 'minus' or 'add')
  752. $element = new $classname($db);
  753. $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
  754. if (is_array($elementarray) && count($elementarray) > 0) {
  755. $total_ht = 0;
  756. $total_ttc = 0;
  757. // Loop on each object for the current element type
  758. $num = count($elementarray);
  759. for ($i = 0; $i < $num; $i++) {
  760. $tmp = explode('_', $elementarray[$i]);
  761. $idofelement = $tmp[0];
  762. $idofelementuser = !empty($tmp[1]) ? $tmp[1] : "";
  763. $element->fetch($idofelement);
  764. if ($idofelementuser) {
  765. $elementuser->fetch($idofelementuser);
  766. }
  767. // Define if record must be used for total or not
  768. $qualifiedfortotal = true;
  769. if ($key == 'invoice') {
  770. if (!empty($element->close_code) && $element->close_code == 'replaced') {
  771. $qualifiedfortotal = false; // Replacement invoice, do not include into total
  772. }
  773. if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS') && $element->type == Facture::TYPE_DEPOSIT) {
  774. $qualifiedfortotal = false; // If hidden option to use deposits as payment (deprecated, not recommended to use this), deposits are not included
  775. }
  776. }
  777. if ($key == 'propal') {
  778. if ($element->status != Propal::STATUS_SIGNED && $element->status != Propal::STATUS_BILLED) {
  779. $qualifiedfortotal = false; // Only signed proposal must not be included in total
  780. }
  781. }
  782. if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) {
  783. $element->fetch_thirdparty();
  784. }
  785. // Define $total_ht_by_line
  786. if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
  787. $total_ht_by_line = $element->amount;
  788. } elseif ($tablename == 'fichinter') {
  789. $total_ht_by_line = $element->getAmount();
  790. } elseif ($tablename == 'stock_mouvement') {
  791. $total_ht_by_line = $element->price * abs($element->qty);
  792. } elseif ($tablename == 'projet_task') {
  793. $tmp = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee);
  794. $total_ht_by_line = price2num($tmp['amount'], 'MT');
  795. } elseif ($key == 'loan') {
  796. if ((empty($dates) && empty($datee)) || (intval($dates) <= $element->datestart && intval($datee) >= $element->dateend)) {
  797. // Get total loan
  798. $total_ht_by_line = -$element->capital;
  799. } else {
  800. // Get loan schedule according to date filter
  801. $total_ht_by_line = 0;
  802. $loanScheduleStatic = new LoanSchedule($element->db);
  803. $loanScheduleStatic->fetchAll($element->id);
  804. if (!empty($loanScheduleStatic->lines)) {
  805. foreach ($loanScheduleStatic->lines as $loanSchedule) {
  806. /**
  807. * @var $loanSchedule LoanSchedule
  808. */
  809. if (($loanSchedule->datep >= $dates && $loanSchedule->datep <= $datee) // dates filter is defined
  810. || !empty($dates) && empty($datee) && $loanSchedule->datep >= $dates && $loanSchedule->datep <= dol_now()
  811. || empty($dates) && !empty($datee) && $loanSchedule->datep <= $datee
  812. ) {
  813. $total_ht_by_line -= $loanSchedule->amount_capital;
  814. }
  815. }
  816. }
  817. }
  818. } else {
  819. $total_ht_by_line = $element->total_ht;
  820. }
  821. // Define $total_ttc_by_line
  822. if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
  823. $total_ttc_by_line = $element->amount;
  824. } elseif ($tablename == 'fichinter') {
  825. $total_ttc_by_line = $element->getAmount();
  826. } elseif ($tablename == 'stock_mouvement') {
  827. $total_ttc_by_line = $element->price * abs($element->qty);
  828. } elseif ($tablename == 'projet_task') {
  829. $defaultvat = get_default_tva($mysoc, $mysoc);
  830. $reg = array();
  831. if (preg_replace('/^(\d+\.)\s\(.*\)/', $defaultvat, $reg)) {
  832. $defaultvat = $reg[1];
  833. }
  834. $total_ttc_by_line = price2num($total_ht_by_line * (1 + ((float) $defaultvat / 100)), 'MT');
  835. } elseif ($key == 'loan') {
  836. $total_ttc_by_line = $total_ht_by_line; // For loan there is actually no taxe managed in Dolibarr
  837. } else {
  838. $total_ttc_by_line = $element->total_ttc;
  839. }
  840. // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
  841. if ($tablename == 'payment_various') {
  842. if ($element->sens == 1) {
  843. $total_ht_by_line = -$total_ht_by_line;
  844. $total_ttc_by_line = -$total_ttc_by_line;
  845. }
  846. }
  847. // Add total if we have to
  848. if ($qualifiedfortotal) {
  849. $total_ht = $total_ht + $total_ht_by_line;
  850. $total_ttc = $total_ttc + $total_ttc_by_line;
  851. }
  852. }
  853. // Each element with at least one line is output
  854. // Calculate margin
  855. if ($margin) {
  856. if ($margin === 'add') {
  857. $total_revenue_ht += $total_ht;
  858. }
  859. if ($margin === "minus") { // Revert sign
  860. $total_ht = -$total_ht;
  861. $total_ttc = -$total_ttc;
  862. }
  863. $balance_ht += $total_ht;
  864. $balance_ttc += $total_ttc;
  865. }
  866. print '<tr class="oddeven">';
  867. // Module
  868. print '<td class="left">'.$name.'</td>';
  869. // Nb
  870. print '<td class="right">'.$i.'</td>';
  871. // Amount HT
  872. print '<td class="right">';
  873. if ($key == 'intervention' && !$margin) {
  874. print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
  875. } else {
  876. if ($key == 'propal') {
  877. print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
  878. }
  879. print price($total_ht);
  880. }
  881. print '</td>';
  882. // Amount TTC
  883. print '<td class="right">';
  884. if ($key == 'intervention' && !$margin) {
  885. print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
  886. } else {
  887. if ($key == 'propal') {
  888. print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
  889. }
  890. print price($total_ttc);
  891. }
  892. print '</td>';
  893. print '</tr>';
  894. }
  895. }
  896. }
  897. // and the final balance
  898. print '<tr class="liste_total">';
  899. print '<td class="right" colspan="2">'.$langs->trans("Profit").'</td>';
  900. print '<td class="right">'.price(price2num($balance_ht, 'MT')).'</td>';
  901. print '<td class="right">'.price(price2num($balance_ttc, 'MT')).'</td>';
  902. print '</tr>';
  903. // and the margin (profit / revenues)
  904. if ($total_revenue_ht) {
  905. print '<tr class="liste_total">';
  906. print '<td class="right" colspan="2">'.$langs->trans("Margin").'</td>';
  907. print '<td class="right">'.round(100 * $balance_ht / $total_revenue_ht, 1).'%</td>';
  908. print '<td class="right"></td>';
  909. print '</tr>';
  910. }
  911. print "</table>";
  912. print '<br><br>';
  913. print '<br>';
  914. $total_time = 0;
  915. // Detail
  916. foreach ($listofreferent as $key => $value) {
  917. $parameters = array(
  918. 'key' => $key,
  919. 'value' =>& $value,
  920. 'dates' => $dates,
  921. 'datee' => $datee
  922. );
  923. $reshook = $hookmanager->executeHooks('printOverviewDetail', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  924. if ($reshook < 0) {
  925. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  926. } elseif ($reshook > 0) {
  927. print $hookmanager->resPrint;
  928. continue;
  929. }
  930. $title = $value['title'];
  931. $classname = $value['class'];
  932. $tablename = $value['table'];
  933. $datefieldname = $value['datefieldname'];
  934. $qualified = $value['test'];
  935. $urlnew = empty($value['urlnew']) ? '' : $value['urlnew'];
  936. $buttonnew = empty($value['buttonnew']) ? '' : $value['buttonnew'];
  937. $testnew = empty($value['testnew']) ? '' : $value['testnew'];
  938. $project_field = empty($value['project_field']) ? '' : $value['project_field'];
  939. $nototal = empty($value['nototal']) ? 0 : 1;
  940. $exclude_select_element = array('payment_various');
  941. if (!empty($value['exclude_select_element'])) {
  942. $exclude_select_element[] = $value['exclude_select_element'];
  943. }
  944. if ($qualified) {
  945. // If we want the project task array to have details of users
  946. //if ($key == 'project_task') $key = 'project_task_time';
  947. $element = new $classname($db);
  948. $addform = '';
  949. $idtofilterthirdparty = 0;
  950. $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur');
  951. if (!in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) {
  952. $idtofilterthirdparty = empty($object->thirdparty->id) ? 0 : $object->thirdparty->id;
  953. if (getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS')) {
  954. $idtofilterthirdparty .= ',' . getDolGlobalString('PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS');
  955. }
  956. }
  957. $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field) ? $project_field : 'fk_projet');
  958. if (!getDolGlobalString('PROJECT_LINK_ON_OVERWIEW_DISABLED') && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) {
  959. $selectList = $formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300 minwidth75imp', -2, empty($project_field) ? 'fk_projet' : $project_field, $langs->trans("SelectElement"));
  960. if ($selectList < 0) {
  961. setEventMessages($formproject->error, $formproject->errors, 'errors');
  962. } elseif ($selectList) {
  963. // Define form with the combo list of elements to link
  964. $addform .= '<div class="inline-block valignmiddle">';
  965. $addform .= '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
  966. $addform .= '<input type="hidden" name="token" value="'.newToken().'">';
  967. $addform .= '<input type="hidden" name="tablename" value="'.$tablename.'">';
  968. $addform .= '<input type="hidden" name="action" value="addelement">';
  969. $addform .= '<input type="hidden" name="datesrfc" value="'.dol_print_date($dates, 'dayhourrfc').'">';
  970. $addform .= '<input type="hidden" name="dateerfc" value="'.dol_print_date($datee, 'dayhourrfc').'">';
  971. $addform .= '<table><tr>';
  972. //$addform .= '<td><span class="hideonsmartphone opacitymedium">'.$langs->trans("SelectElement").'</span></td>';
  973. $addform .= '<td>'.$selectList.'</td>';
  974. $addform .= '<td><input type="submit" class="button button-linkto smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("LinkToElementShort")).'"></td>';
  975. $addform .= '</tr></table>';
  976. $addform .= '</form>';
  977. $addform .= '</div>';
  978. }
  979. }
  980. if (!getDolGlobalString('PROJECT_CREATE_ON_OVERVIEW_DISABLED') && $urlnew) {
  981. $addform .= '<div class="inline-block valignmiddle">';
  982. if ($testnew) {
  983. $addform .= '<a class="buttonxxx marginleftonly" href="'.$urlnew.'" title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a>';
  984. } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
  985. $addform .= '<span title="'.dol_escape_htmltag($langs->trans($buttonnew)).'"><a class="buttonxxx marginleftonly buttonRefused" disabled="disabled" href="#"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a></span>';
  986. }
  987. $addform .= '<div>';
  988. }
  989. if (is_array($elementarray) && count($elementarray) > 0 && $key == "order_supplier") {
  990. $addform = '<div class="inline-block valignmiddle"><a id="btnShow" class="buttonxxx marginleftonly" href="#" onClick="return false;">
  991. <span id="textBtnShow" class="valignmiddle text-plus-circle hideonsmartphone">'.$langs->trans("CanceledShown").'</span><span id="minus-circle" class="fa fa-eye valignmiddle paddingleft"></span>
  992. </a>
  993. <script>
  994. $("#btnShow").on("click", function () {
  995. console.log("We click to show or hide the canceled lines");
  996. var attr = $(this).attr("data-canceledarehidden");
  997. if (typeof attr !== "undefined" && attr !== false) {
  998. console.log("Show canceled");
  999. $(".tr_canceled").show();
  1000. $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledShown")).'");
  1001. $("#btnShow").removeAttr("data-canceledarehidden");
  1002. $("#minus-circle").removeClass("fa-eye-slash").addClass("fa-eye");
  1003. } else {
  1004. console.log("Hide canceled");
  1005. $(".tr_canceled").hide();
  1006. $("#textBtnShow").text("'.dol_escape_js($langs->transnoentitiesnoconv("CanceledHidden")).'");
  1007. $("#btnShow").attr("data-canceledarehidden", 1);
  1008. $("#minus-circle").removeClass("fa-eye").addClass("fa-eye-slash");
  1009. }
  1010. });
  1011. </script></div> '.$addform;
  1012. }
  1013. print load_fiche_titre($langs->trans($title), $addform, '');
  1014. print "\n".'<!-- Table for tablename = '.$tablename.' -->'."\n";
  1015. print '<div class="div-table-responsive">';
  1016. print '<table class="noborder centpercent">';
  1017. print '<tr class="liste_titre">';
  1018. // Remove link column
  1019. print '<td style="width: 24px"></td>';
  1020. // Ref
  1021. print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').'>'.$langs->trans("Ref").'</td>';
  1022. // Date
  1023. print '<td'.(($tablename != 'actioncomm' && $tablename != 'projet_task') ? ' style="width: 200px"' : '').' class="center">';
  1024. if (in_array($tablename, array('projet_task'))) {
  1025. print $langs->trans("TimeSpent");
  1026. }
  1027. if (!in_array($tablename, array('projet_task'))) {
  1028. print $langs->trans("Date");
  1029. }
  1030. print '</td>';
  1031. // Thirdparty or user
  1032. print '<td>';
  1033. if (in_array($tablename, array('projet_task')) && $key == 'project_task') {
  1034. print ''; // if $key == 'project_task', we don't want details per user
  1035. } elseif (in_array($tablename, array('payment_various'))) {
  1036. print ''; // if $key == 'payment_various', we don't have any thirdparty
  1037. } elseif (in_array($tablename, array('expensereport_det', 'don', 'projet_task', 'stock_mouvement', 'salary'))) {
  1038. print $langs->trans("User");
  1039. } else {
  1040. print $langs->trans("ThirdParty");
  1041. }
  1042. print '</td>';
  1043. // Duration of intervention
  1044. if ($tablename == 'fichinter') {
  1045. print '<td>';
  1046. print $langs->trans("TotalDuration");
  1047. $total_duration = 0;
  1048. print '</td>';
  1049. }
  1050. // Amount HT
  1051. //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
  1052. //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("Amount").'</td>';
  1053. if ($key == 'loan') {
  1054. print '<td class="right" width="120">'.$langs->trans("LoanCapital").'</td>';
  1055. } elseif (empty($value['disableamount'])) {
  1056. print '<td class="right" width="120">'.$langs->trans("AmountHT").'</td>';
  1057. } else {
  1058. print '<td width="120"></td>';
  1059. }
  1060. // Amount TTC
  1061. //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
  1062. if ($key == 'loan') {
  1063. print '<td class="right" width="120">'.$langs->trans("RemainderToPay").'</td>';
  1064. } elseif (empty($value['disableamount'])) {
  1065. print '<td class="right" width="120">'.$langs->trans("AmountTTC").'</td>';
  1066. } else {
  1067. print '<td width="120"></td>';
  1068. }
  1069. // Status
  1070. if (in_array($tablename, array('projet_task'))) {
  1071. print '<td class="right" width="200">'.$langs->trans("ProgressDeclared").'</td>';
  1072. } else {
  1073. print '<td class="right" width="200">'.$langs->trans("Status").'</td>';
  1074. }
  1075. print '</tr>';
  1076. if (is_array($elementarray) && count($elementarray) > 0) {
  1077. $total_ht = 0;
  1078. $total_ttc = 0;
  1079. $total_ht_by_third = 0;
  1080. $total_ttc_by_third = 0;
  1081. $saved_third_id = 0;
  1082. $breakline = '';
  1083. if (canApplySubtotalOn($tablename)) {
  1084. // Sort
  1085. $elementarray = sortElementsByClientName($elementarray);
  1086. }
  1087. $num = count($elementarray);
  1088. for ($i = 0; $i < $num; $i++) {
  1089. $tmp = explode('_', $elementarray[$i]);
  1090. $idofelement = $tmp[0];
  1091. $idofelementuser = isset($tmp[1]) ? $tmp[1] : "";
  1092. $element->fetch($idofelement);
  1093. if ($idofelementuser) {
  1094. $elementuser->fetch($idofelementuser);
  1095. }
  1096. // Special cases
  1097. if ($tablename != 'expensereport_det') {
  1098. if (method_exists($element, 'fetch_thirdparty')) {
  1099. $element->fetch_thirdparty();
  1100. }
  1101. } else {
  1102. $expensereport = new ExpenseReport($db);
  1103. $expensereport->fetch($element->fk_expensereport);
  1104. }
  1105. //print 'xxx'.$tablename.'yyy'.$classname;
  1106. if ($breakline && $saved_third_id != $element->thirdparty->id) {
  1107. print $breakline;
  1108. $saved_third_id = $element->thirdparty->id;
  1109. $breakline = '';
  1110. $total_ht_by_third = 0;
  1111. $total_ttc_by_third = 0;
  1112. }
  1113. $saved_third_id = empty($element->thirdparty->id) ? 0 : $element->thirdparty->id;
  1114. $qualifiedfortotal = true;
  1115. if ($key == 'invoice') {
  1116. if (!empty($element->close_code) && $element->close_code == 'replaced') {
  1117. $qualifiedfortotal = false; // Replacement invoice, do not include into total
  1118. }
  1119. } elseif ($key == 'order_supplier' && $element->status == 7) {
  1120. $qualifiedfortotal = false; // It makes no sense to include canceled orders in the total
  1121. }
  1122. if ($key == "order_supplier" && $element->status == 7) {
  1123. print '<tr class="oddeven tr_canceled" style=display:none>';
  1124. } else {
  1125. print '<tr class="oddeven" >';
  1126. }
  1127. // Remove link
  1128. print '<td style="width: 24px">';
  1129. if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') {
  1130. if (!getDolGlobalString('PROJECT_DISABLE_UNLINK_FROM_OVERVIEW') || $user->admin) { // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by defaut, so this test true
  1131. print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=unlink&tablename='.$tablename.'&elementselect='.$element->id.($project_field ? '&projectfield='.$project_field : '').'" class="reposition">';
  1132. print img_picto($langs->trans('Unlink'), 'unlink');
  1133. print '</a>';
  1134. }
  1135. }
  1136. print "</td>\n";
  1137. // Ref
  1138. print '<td class="left nowraponall tdoverflowmax250">';
  1139. if ($tablename == 'expensereport_det') {
  1140. print $expensereport->getNomUrl(1);
  1141. } else {
  1142. // Show ref with link
  1143. if ($element instanceof Task) {
  1144. print $element->getNomUrl(1, 'withproject', 'time');
  1145. print ' - '.dol_trunc($element->label, 48);
  1146. } elseif ($key == 'loan') {
  1147. print $element->getNomUrl(1);
  1148. print ' - '.dol_trunc($element->label, 48);
  1149. } else {
  1150. print $element->getNomUrl(1);
  1151. }
  1152. $element_doc = $element->element;
  1153. $filename = dol_sanitizeFileName($element->ref);
  1154. if (!empty($conf->$element_doc)) {
  1155. $confelementdoc = $conf->$element_doc;
  1156. $filedir = $confelementdoc->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
  1157. } else {
  1158. $filedir = '';
  1159. }
  1160. if ($element_doc === 'order_supplier') {
  1161. $element_doc = 'commande_fournisseur';
  1162. $filedir = $conf->fournisseur->commande->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
  1163. } elseif ($element_doc === 'invoice_supplier') {
  1164. $element_doc = 'facture_fournisseur';
  1165. $filename = get_exdir($element->id, 2, 0, 0, $element, 'product').dol_sanitizeFileName($element->ref);
  1166. $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
  1167. }
  1168. print '<div class="inline-block valignmiddle">';
  1169. if ($filedir) {
  1170. print $formfile->getDocumentsLink($element_doc, $filename, $filedir);
  1171. }
  1172. print '</div>';
  1173. // Show supplier ref
  1174. if (!empty($element->ref_supplier)) {
  1175. print ' - '.$element->ref_supplier;
  1176. }
  1177. // Show customer ref
  1178. if (!empty($element->ref_customer)) {
  1179. print ' - '.$element->ref_customer;
  1180. }
  1181. // Compatibility propale
  1182. if (empty($element->ref_customer) && !empty($element->ref_client)) {
  1183. print ' - '.$element->ref_client;
  1184. }
  1185. }
  1186. print "</td>\n";
  1187. // Date or TimeSpent
  1188. $date = '';
  1189. $total_time_by_line = null;
  1190. if ($tablename == 'expensereport_det') {
  1191. $date = $element->date; // No draft status on lines
  1192. } elseif ($tablename == 'stock_mouvement') {
  1193. $date = $element->datem;
  1194. } elseif ($tablename == 'salary') {
  1195. $date = $element->datesp;
  1196. } elseif ($tablename == 'payment_various') {
  1197. $date = $element->datev;
  1198. } elseif ($tablename == 'chargesociales') {
  1199. $date = $element->date_ech;
  1200. } elseif (!empty($element->status) || !empty($element->statut) || !empty($element->fk_status)) {
  1201. if ($tablename == 'don') {
  1202. $date = $element->datedon;
  1203. }
  1204. if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') {
  1205. $date = ($element->date_commande ? $element->date_commande : $element->date_valid);
  1206. } elseif ($tablename == 'supplier_proposal') {
  1207. $date = $element->date_validation; // There is no other date for this
  1208. } elseif ($tablename == 'fichinter') {
  1209. $date = $element->datev; // There is no other date for this
  1210. } elseif ($tablename == 'projet_task') {
  1211. $date = ''; // We show no date. Showing date of beginning of task make user think it is date of time consumed
  1212. } else {
  1213. $date = $element->date; // invoice, ...
  1214. if (empty($date)) {
  1215. $date = $element->date_contrat;
  1216. }
  1217. if (empty($date)) {
  1218. $date = $element->datev;
  1219. }
  1220. if (empty($date) && !empty($datefieldname)) {
  1221. $date = $element->$datefieldname;
  1222. }
  1223. }
  1224. } elseif ($key == 'loan') {
  1225. $date = $element->datestart;
  1226. }
  1227. print '<td class="center">';
  1228. if ($tablename == 'actioncomm') {
  1229. print dol_print_date($element->datep, 'dayhour');
  1230. if ($element->datef && $element->datef > $element->datep) {
  1231. print " - ".dol_print_date($element->datef, 'dayhour');
  1232. }
  1233. } elseif (in_array($tablename, array('projet_task'))) {
  1234. $tmpprojtime = $element->getSumOfAmount($idofelementuser ? $elementuser : '', $dates, $datee); // $element is a task. $elementuser may be empty
  1235. print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$idofelement.'&withproject=1">';
  1236. print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin');
  1237. print '</a>';
  1238. $total_time_by_line = $tmpprojtime['nbseconds'];
  1239. } else {
  1240. print dol_print_date($date, 'day');
  1241. }
  1242. print '</td>';
  1243. // Third party or user
  1244. print '<td class="tdoverflowmax150">';
  1245. if (is_object($element->thirdparty)) {
  1246. print $element->thirdparty->getNomUrl(1, '', 48);
  1247. } elseif ($tablename == 'expensereport_det') {
  1248. $tmpuser = new User($db);
  1249. $tmpuser->fetch($expensereport->fk_user_author);
  1250. print $tmpuser->getNomUrl(1, '', 48);
  1251. } elseif ($tablename == 'salary') {
  1252. $tmpuser = new User($db);
  1253. $tmpuser->fetch($element->fk_user);
  1254. print $tmpuser->getNomUrl(1, '', 48);
  1255. } elseif ($tablename == 'don' || $tablename == 'stock_mouvement') {
  1256. if ($element->fk_user_author > 0) {
  1257. $tmpuser2 = new User($db);
  1258. $tmpuser2->fetch($element->fk_user_author);
  1259. print $tmpuser2->getNomUrl(1, '', 48);
  1260. }
  1261. } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user
  1262. print $elementuser->getNomUrl(1);
  1263. }
  1264. print '</td>';
  1265. // Add duration and store it in counter for fichinter
  1266. if ($tablename == 'fichinter') {
  1267. print '<td>';
  1268. print convertSecondToTime($element->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
  1269. $total_duration += $element->duration;
  1270. print '</td>';
  1271. }
  1272. // Amount without tax
  1273. $warning = '';
  1274. if (empty($value['disableamount'])) {
  1275. $total_ht_by_line = null;
  1276. $othermessage = '';
  1277. if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
  1278. $total_ht_by_line = $element->amount;
  1279. } elseif ($tablename == 'fichinter') {
  1280. $total_ht_by_line = $element->getAmount();
  1281. } elseif ($tablename == 'stock_mouvement') {
  1282. $total_ht_by_line = $element->price * abs($element->qty);
  1283. } elseif (in_array($tablename, array('projet_task'))) {
  1284. if (isModEnabled('salaries')) {
  1285. // TODO Permission to read daily rate to show value
  1286. $total_ht_by_line = price2num($tmpprojtime['amount'], 'MT');
  1287. if ($tmpprojtime['nblinesnull'] > 0) {
  1288. $langs->load("errors");
  1289. $warning = $langs->trans("WarningSomeLinesWithNullHourlyRate", $conf->currency);
  1290. }
  1291. } else {
  1292. $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
  1293. }
  1294. } elseif ($key == 'loan') {
  1295. $total_ht_by_line = $element->capital;
  1296. } else {
  1297. $total_ht_by_line = $element->total_ht;
  1298. }
  1299. // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
  1300. if ($tablename == 'payment_various') {
  1301. if ($element->sens == 0) {
  1302. $total_ht_by_line = -$total_ht_by_line;
  1303. }
  1304. }
  1305. print '<td class="right">';
  1306. if ($othermessage) {
  1307. print $othermessage;
  1308. }
  1309. if (isset($total_ht_by_line)) {
  1310. if (!$qualifiedfortotal) {
  1311. print '<strike>';
  1312. }
  1313. print '<span class="amount">'.price($total_ht_by_line).'</span>';
  1314. if (!$qualifiedfortotal) {
  1315. print '</strike>';
  1316. }
  1317. }
  1318. if ($warning) {
  1319. print ' '.img_warning($warning);
  1320. }
  1321. print '</td>';
  1322. } else {
  1323. print '<td></td>';
  1324. }
  1325. // Amount inc tax
  1326. if (empty($value['disableamount'])) {
  1327. $total_ttc_by_line = null;
  1328. if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'salary') {
  1329. $total_ttc_by_line = $element->amount;
  1330. } elseif ($tablename == 'fichinter') {
  1331. $total_ttc_by_line = $element->getAmount();
  1332. } elseif ($tablename == 'stock_mouvement') {
  1333. $total_ttc_by_line = $element->price * abs($element->qty);
  1334. } elseif ($tablename == 'projet_task') {
  1335. if (isModEnabled('salaries')) {
  1336. // TODO Permission to read daily rate
  1337. $defaultvat = get_default_tva($mysoc, $mysoc);
  1338. $total_ttc_by_line = price2num($total_ht_by_line * (1 + ($defaultvat / 100)), 'MT');
  1339. } else {
  1340. $othermessage = $form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled"));
  1341. }
  1342. } elseif ($key == 'loan') {
  1343. $total_ttc_by_line = $element->capital - $element->getSumPayment();
  1344. } else {
  1345. $total_ttc_by_line = $element->total_ttc;
  1346. }
  1347. // Change sign of $total_ht_by_line and $total_ttc_by_line for some cases
  1348. if ($tablename == 'payment_various') {
  1349. if ($element->sens == 0) {
  1350. $total_ttc_by_line = -$total_ttc_by_line;
  1351. }
  1352. }
  1353. print '<td class="right">';
  1354. if ($othermessage) {
  1355. print $othermessage;
  1356. }
  1357. if (isset($total_ttc_by_line)) {
  1358. if (!$qualifiedfortotal) {
  1359. print '<strike>';
  1360. }
  1361. print '<span class="amount">'.price($total_ttc_by_line).'</span>';
  1362. if (!$qualifiedfortotal) {
  1363. print '</strike>';
  1364. }
  1365. }
  1366. if ($warning) {
  1367. print ' '.img_warning($warning);
  1368. }
  1369. print '</td>';
  1370. } else {
  1371. print '<td></td>';
  1372. }
  1373. // Status
  1374. print '<td class="right">';
  1375. if ($tablename == 'expensereport_det') {
  1376. print $expensereport->getLibStatut(5);
  1377. } elseif ($element instanceof CommonInvoice) {
  1378. //This applies for Facture and FactureFournisseur
  1379. print $element->getLibStatut(5, $element->getSommePaiement());
  1380. } elseif ($element instanceof Task) {
  1381. if ($element->progress != '') {
  1382. print $element->progress.' %';
  1383. }
  1384. } elseif ($tablename == 'stock_mouvement') {
  1385. print $element->getLibStatut(3);
  1386. } else {
  1387. print $element->getLibStatut(5);
  1388. }
  1389. print '</td>';
  1390. print '</tr>';
  1391. if ($qualifiedfortotal) {
  1392. $total_ht = $total_ht + $total_ht_by_line;
  1393. $total_ttc = $total_ttc + $total_ttc_by_line;
  1394. $total_ht_by_third += $total_ht_by_line;
  1395. $total_ttc_by_third += $total_ttc_by_line;
  1396. if (!isset($total_time)) {
  1397. $total_time = $total_time_by_line;
  1398. } else {
  1399. $total_time += $total_time_by_line;
  1400. }
  1401. }
  1402. if (canApplySubtotalOn($tablename)) {
  1403. $breakline = '<tr class="liste_total liste_sub_total">';
  1404. $breakline .= '<td colspan="2">';
  1405. $breakline .= '</td>';
  1406. $breakline .= '<td>';
  1407. $breakline .= '</td>';
  1408. $breakline .= '<td class="right">';
  1409. $breakline .= $langs->trans('SubTotal').' : ';
  1410. if (is_object($element->thirdparty)) {
  1411. $breakline .= $element->thirdparty->getNomUrl(0, '', 48);
  1412. }
  1413. $breakline .= '</td>';
  1414. $breakline .= '<td class="right">'.price($total_ht_by_third).'</td>';
  1415. $breakline .= '<td class="right">'.price($total_ttc_by_third).'</td>';
  1416. $breakline .= '<td></td>';
  1417. $breakline .= '</tr>';
  1418. }
  1419. //var_dump($element->thirdparty->name.' - '.$saved_third_id.' - '.$element->thirdparty->id);
  1420. }
  1421. if ($breakline) {
  1422. print $breakline;
  1423. }
  1424. // Total
  1425. if (empty($nototal)) {
  1426. $colspan = 4;
  1427. if (in_array($tablename, array('projet_task'))) {
  1428. $colspan = 2;
  1429. }
  1430. print '<tr class="liste_total"><td colspan="'.$colspan.'">'.$langs->trans("Number").': '.$i.'</td>';
  1431. if (in_array($tablename, array('projet_task'))) {
  1432. print '<td class="center">';
  1433. print convertSecondToTime($total_time, 'allhourmin');
  1434. print '</td>';
  1435. print '<td>';
  1436. print '</td>';
  1437. }
  1438. //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_ht).'</td>';
  1439. //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("Total").' : '.price($total_ht).'</td>';
  1440. // If fichinter add the total_duration
  1441. if ($tablename == 'fichinter') {
  1442. print '<td class="left">'.convertSecondToTime($total_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
  1443. }
  1444. print '<td class="right">';
  1445. if (empty($value['disableamount'])) {
  1446. if ($key == 'loan') {
  1447. print $langs->trans("Total").' '.$langs->trans("LoanCapital").' : '.price($total_ttc);
  1448. } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
  1449. print ''.$langs->trans("TotalHT").' : '.price($total_ht);
  1450. }
  1451. }
  1452. print '</td>';
  1453. //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print '<td class="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_ttc).'</td>';
  1454. //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print '<td class="right" width="100"></td>';
  1455. print '<td class="right">';
  1456. if (empty($value['disableamount'])) {
  1457. if ($key == 'loan') {
  1458. print $langs->trans("Total").' '.$langs->trans("RemainderToPay").' : '.price($total_ttc);
  1459. } elseif ($tablename != 'projet_task' || isModEnabled('salaries')) {
  1460. print $langs->trans("TotalTTC").' : '.price($total_ttc);
  1461. }
  1462. }
  1463. print '</td>';
  1464. print '<td>&nbsp;</td>';
  1465. print '</tr>';
  1466. }
  1467. } else {
  1468. if (!is_array($elementarray)) { // error
  1469. print '<tr><td>'.$elementarray.'</td></tr>';
  1470. } else {
  1471. $colspan = 7;
  1472. if ($tablename == 'fichinter') {
  1473. $colspan++;
  1474. }
  1475. print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</td></tr>';
  1476. }
  1477. }
  1478. print "</table>";
  1479. print '</div>';
  1480. print "<br>\n";
  1481. }
  1482. }
  1483. // Enhance with select2
  1484. if ($conf->use_javascript_ajax) {
  1485. include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
  1486. $comboenhancement = ajax_combobox('.elementselect');
  1487. print $comboenhancement;
  1488. }
  1489. // End of page
  1490. llxFooter();
  1491. $db->close();
  1492. /**
  1493. * Return if we should do a group by customer with sub-total
  1494. *
  1495. * @param string $tablename Name of table
  1496. * @return boolean True to tell to make a group by sub-total
  1497. */
  1498. function canApplySubtotalOn($tablename)
  1499. {
  1500. global $conf;
  1501. if (!getDolGlobalString('PROJECT_ADD_SUBTOTAL_LINES')) {
  1502. return false;
  1503. }
  1504. return in_array($tablename, array('facture_fourn', 'commande_fournisseur'));
  1505. }
  1506. /**
  1507. * sortElementsByClientName
  1508. *
  1509. * @param array $elementarray Element array
  1510. * @return array Element array sorted
  1511. */
  1512. function sortElementsByClientName($elementarray)
  1513. {
  1514. global $db, $classname;
  1515. $element = new $classname($db);
  1516. $clientname = array();
  1517. foreach ($elementarray as $key => $id) { // id = id of object
  1518. if (empty($clientname[$id])) {
  1519. $element->fetch($id);
  1520. $element->fetch_thirdparty();
  1521. $clientname[$id] = $element->thirdparty->name;
  1522. }
  1523. }
  1524. //var_dump($clientname);
  1525. asort($clientname); // sort on name
  1526. $elementarray = array();
  1527. foreach ($clientname as $id => $name) {
  1528. $elementarray[] = $id;
  1529. }
  1530. return $elementarray;
  1531. }