element.php 62 KB

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