浏览代码

Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop

Laurent Destailleur 1 年之前
父节点
当前提交
e91f0d88c8

+ 15 - 0
htdocs/contrat/class/contrat.class.php

@@ -2492,6 +2492,21 @@ class Contrat extends CommonObject
 		return $this->fetch_lines();
 	}
 
+	/**
+	 * 	Create an array of associated tickets
+	 *
+	 * 	@return array|int		Array o tickets or <0 if KO
+	 */
+	public function getTicketsArray()
+	{
+		global $user;
+
+		$ticket = new Ticket($this->db);
+		$nbTicket =  $ticket->fetchAll($user,  'ASC', 't.datec',  '', 0, '', array('t.fk_contract' => $this->id));
+
+		return ($nbTicket < 0 ? $nbTicket : $ticket->lines);
+	}
+
 
 	/**
 	 *  Create a document onto disk according to template module.

+ 185 - 0
htdocs/contrat/ticket.php

@@ -0,0 +1,185 @@
+<?php
+/* Copyright (C) 2004		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
+ * Copyright (C) 2004-2016	Laurent Destailleur		<eldy@users.sourceforge.net>
+ * Copyright (C) 2012-2023		Charlene BENKE		<charlene@patas-monkey.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *	  	\file	   	htdocs/contrat/ticket.php
+ *	  	\ingroup	contrat
+ *		\brief	 	Page of associated ticket
+ */
+
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
+if (isModEnabled('project')) {
+	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+}
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php";
+
+$langs->loadLangs(array('companies', 'contracts', 'tickets'));
+
+$socid=GETPOST('socid', 'int');
+$id=GETPOST('id', 'int');
+$ref=GETPOST('ref', 'alpha');
+$action=GETPOST('action', 'alpha');
+
+if ($id == '' && $ref == '') {
+	dol_print_error('', 'Bad parameter');
+	exit;
+}
+
+// Security check
+$socid=0;
+if ($user->socid > 0)
+	$socid=$user->socid;
+
+$result=restrictedArea($user, 'contrat', $id);
+
+
+/*
+ *	View
+ */
+
+llxHeader("", $langs->trans("Tickets"), "Contrat");
+
+$form = new Form($db);
+$userstatic=new User($db);
+
+$object= new Contrat($db);
+$result=$object->fetch($id, $ref);
+$ret=$object->fetch_thirdparty();
+$head = contract_prepare_head($object);
+
+
+dol_fiche_head($head, 'ticket', $langs->trans("Contract"), -1, 'contract');
+
+$linkback = '<a href="'.DOL_URL_ROOT.'/contrat/list.php'.(! empty($socid)?'?socid='.$socid:'').'">';
+$linkback.= $langs->trans("BackToList").'</a>';
+
+$morehtmlref='';
+$morehtmlref.=$object->ref;
+
+$morehtmlref.='<div class="refidno">';
+// Ref customer
+$morehtmlref.=$form->editfieldkey(
+				"RefCustomer", 'ref_customer', $object->ref_customer,
+				$object, 0, 'string', '', 0, 1
+);
+$morehtmlref.=$form->editfieldval(
+				"RefCustomer", 'ref_customer', $object->ref_customer,
+				$object, 0, 'string', '', null, null, '', 1
+);
+// Ref supplier
+$morehtmlref.='<br>';
+$morehtmlref.=$form->editfieldkey(
+				"RefSupplier", 'ref_supplier', $object->ref_supplier,
+				$object, 0, 'string', '', 0, 1
+);
+$morehtmlref.=$form->editfieldval(
+				"RefSupplier", 'ref_supplier', $object->ref_supplier,
+				$object, 0, 'string', '', null, null, '', 1
+);
+// Thirdparty
+$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
+// Project
+if (! empty($conf->projet->enabled)) {
+	require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
+
+	$langs->load("projects");
+	$morehtmlref.='<br>'.$langs->trans('Project') . ' : ';
+	if (! empty($object->fk_project)) {
+		$proj = new Project($db);
+		$proj->fetch($object->fk_project);
+		$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=';
+		$morehtmlref.=$object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
+		$morehtmlref.=$proj->ref;
+		$morehtmlref.='</a>';
+	} else {
+		$morehtmlref.='';
+	}
+}
+$morehtmlref.='</div>';
+
+dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'none', $morehtmlref);
+
+print '<div class="underbanner clearboth"></div>';
+
+
+/*
+ * Referers types
+ */
+
+$title=$langs->trans("ListTicketsLinkToContract");
+
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
+print '<td >'.$langs->trans("Ref").'</td>';
+print '<td width="300">'.$langs->trans("Subject").'</td>';
+print '<td align="left">'.$langs->trans("Type").'</td>';
+print '<td align="left" nowrap >'.$langs->trans("TicketCategory").'</td>';
+print '<td align="left">'.$langs->trans("Severity").'</td>';
+print '<td  align="center">'.$langs->trans("Date").'</td>';
+print '<td  align="center" nowrap >'.$langs->trans("DateEnd").'</td>';
+print '<td  align="right">'.$langs->trans("Progress").'</td>';
+print '<td align="right" width="100">'.$langs->trans("Status").'</td>';
+print '</tr>';
+// on récupère la totalité des tickets liés au contrat
+$allticketarray = $object->getTicketsArray();
+if (is_array($allticketarray) && count($allticketarray) > 0) {
+	foreach ($allticketarray as $key => $value) {
+		$total_ht = 0;
+		$total_ttc = 0;
+
+		$element = $value;
+
+		print "<tr>";
+
+		// Ref
+		print '<td align="left">';
+		print $element->getNomUrl(1);
+		print "</td>\n";
+
+		// Information
+		print '<td align="left">'.$value->subject.'</td>';
+		print '<td align="left">'.$value->type_label.'</td>';
+		print '<td align="left">'.$value->category_label.'</td>';
+		print '<td align="left">'.$value->severity_label.'</td>';
+
+		// Date
+		print '<td align="center">'.dol_print_date($element->datec, 'day').'</td>';
+		print '<td align="center">'.dol_print_date($element->date_close, 'day').'</td>';
+
+		// Duration
+		print '<td align="right">';
+		print (isset($element->progress) ? $element->progress.'%' : '');
+		print '</td>';
+
+		// Status
+		print '<td align="right">'.$element->getLibStatut(5).'</td>';
+		print '</tr>';
+	}
+}
+print "</table>";
+
+
+llxFooter();
+$db->close();

+ 11 - 0
htdocs/core/class/html.formticket.class.php

@@ -4,6 +4,7 @@
  * Copyright (C) 2019-2022 Frédéric France         <frederic.france@netlogic.fr>
  * Copyright (C) 2021      Juanjo Menent           <jmenent@2byte.es>
  * Copyright (C) 2021      Alexandre Spangaro      <aspangaro@open-dsi.fr>
+ * Copyright (C) 2023      Charlene Benke	       <charlene.r@patas-monkey.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -651,6 +652,16 @@ class FormTicket
 			}
 		}
 
+		if ($subelement != 'contract') {
+			if (isModEnabled('contract') && !$this->ispublic) {
+				$formcontract = new FormContract($this->db);
+				print '<tr><td><label for="contract"><span class="">'.$langs->trans("Contract").'</span></label></td><td>';
+				print img_picto('', 'contract');
+				print $formcontract->select_contract(-1, GETPOST('contactid', 'int'), 'contractid', 0, 1, 1);
+				print '</td></tr>';
+			}
+		}
+
 		// Other attributes
 		$parameters = array();
 		$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $ticketstat, $action); // Note that $action and $object may have been modified by hook

+ 8 - 0
htdocs/core/lib/contract.lib.php

@@ -1,6 +1,7 @@
 <?php
 /* Copyright (C) 2006-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2009-2012	Regis Houssin		<regis.houssin@inodbox.com>
+ * Copyright (C) 2023		Charlene BENKE		<charlene@patas-monkey.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,6 +52,13 @@ function contract_prepare_head(Contrat $object)
 		$h++;
 	}
 
+	if (isModEnabled('ticket')) {
+		$head[$h][0] = DOL_URL_ROOT.'/contrat/ticket.php?id='.$object->id;
+		$head[$h][1] = $langs->trans("Tickets");
+		$head[$h][2] = 'ticket';
+		$h++;
+	}
+
 	// Show more tabs from modules
 	// Entries must be declared in modules descriptor with line
 	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab

+ 29 - 2
htdocs/ticket/card.php

@@ -4,7 +4,7 @@
  * Copyright (C) 2018      Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2021      Frédéric France		<frederic.france@netlogic.fr>
  * Copyright (C) 2021      Alexandre Spangaro   <aspangaro@open-dsi.fr>
- * Copyright (C) 2022      Charlene Benke       <charlene@patas-monkey.com>
+ * Copyright (C) 2022-2023 Charlene Benke       <charlene@patas-monkey.com>
  * Copyright (C) 2023      Benjamin Falière		<benjamin.faliere@altairis.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -245,6 +245,7 @@ if (empty($reshook)) {
 			}
 
 			$object->fk_project = $projectid;
+			$object->fk_contract = GETPOST('fk_contract', 'int');
 
 			$id = $object->create($user);
 			if ($id <= 0) {
@@ -813,7 +814,7 @@ if ($action == 'create' || $action == 'presend') {
 
 	print '</form>'; */
 } elseif (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'abandon' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'categories' || $action == 'reopen'
-	|| $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') {
+	|| $action== 'edit_contrat' || $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') {
 	if ($res > 0) {
 		// or for unauthorized internals users
 		if (!$user->socid && (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) {
@@ -1008,6 +1009,32 @@ if ($action == 'create' || $action == 'presend') {
 			}
 		}
 
+		// Contract
+		if (isModEnabled('contrat')) {
+			$langs->load('contracts');
+			$morehtmlref .=  '<br>';
+			$morehtmlref .=  $langs->trans('Contract');
+
+			if ($action != 'edit_contrat') {
+				$morehtmlref .= '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edit_contrat&token='.newToken().'&id='.$object->id.'">';
+				$morehtmlref .=  img_edit($langs->trans('SetContract'), 1);
+				$morehtmlref .=  '</a>';
+			}
+			if ($action == 'edit_contrat') {
+				$formcontract = new Formcontract($db);
+				$morehtmlref .= $formcontract->formSelectContract($_SERVER["PHP_SELF"].'?id='.$object->id, $object->socid, $object->fk_contract, 'contratid', 0, 1, 1, 1);
+			} else {
+				if ($object->fk_contract) {
+					$contratstatic = new Contrat($db);
+					$contratstatic->fetch($object->fk_contract);
+					//print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
+					$morehtmlref .= $contratstatic->getNomUrl(0, '', 1);
+				} else {
+					$morehtmlref .= "&nbsp;";
+				}
+			}
+		}
+
 		$morehtmlref .= '</div>';
 
 		$linkback = '<a href="'.DOL_URL_ROOT.'/ticket/list.php?restore_lastsearch_values=1"><strong>'.$langs->trans("BackToList").'</strong></a> ';

+ 47 - 19
htdocs/ticket/class/ticket.class.php

@@ -3,6 +3,7 @@
  * Copyright (C) 2016      Christophe Battarel <christophe@altairis.fr>
  * Copyright (C) 2019-2023 Frédéric France     <frederic.france@netlogic.fr>
  * Copyright (C) 2020      Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2023      Charlene Benke 	   <charlene@patas-monkey.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,6 +36,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php';
  */
 class Ticket extends CommonObject
 {
+
+	/**
+	 * @var db connector
+	 */
+	public $db;
+
 	/**
 	 * @var string ID to identify managed object
 	 */
@@ -324,6 +331,7 @@ class Ticket extends CommonObject
 		'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>'isModEnabled("societe")', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'searchall'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'css'=>'tdoverflowmax150 maxwidth150onsmartphone'),
 		'notify_tiers_at_create' => array('type'=>'integer', 'label'=>'NotifyThirdparty', 'visible'=>-1, 'enabled'=>0, 'position'=>51, 'notnull'=>1, 'index'=>1),
 		'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php', 'label'=>'Project', 'visible'=>-1, 'enabled'=>'$conf->project->enabled', 'position'=>52, 'notnull'=>-1, 'index'=>1, 'help'=>"LinkToProject"),
+		'fk_contract' => array('type'=>'integer:Contrat:contrat/class/contrat.class.php', 'label'=>'Contract', 'visible'=>-1, 'enabled'=>'$conf->contract->enabled', 'position'=>53, 'notnull'=>-1, 'index'=>1, 'help'=>"LinkToContract"),
 		//'timing' => array('type'=>'varchar(20)', 'label'=>'Timing', 'visible'=>-1, 'enabled'=>1, 'position'=>42, 'notnull'=>-1, 'help'=>""),	// what is this ?
 		'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>1, 'enabled'=>1, 'position'=>500, 'notnull'=>1, 'csslist'=>'nowraponall'),
 		'date_read' => array('type'=>'datetime', 'label'=>'TicketReadOn', 'visible'=>-1, 'enabled'=>1, 'position'=>501, 'notnull'=>1),
@@ -498,6 +506,7 @@ class Ticket extends CommonObject
 			$sql .= "track_id,";
 			$sql .= "fk_soc,";
 			$sql .= "fk_project,";
+			$sql .= "fk_contract,";
 			$sql .= "origin_email,";
 			$sql .= "fk_user_create,";
 			$sql .= "fk_user_assign,";
@@ -523,6 +532,7 @@ class Ticket extends CommonObject
 			$sql .= " ".(!isset($this->track_id) ? 'NULL' : "'".$this->db->escape($this->track_id)."'").",";
 			$sql .= " ".($this->fk_soc > 0 ? $this->db->escape($this->fk_soc) : "null").",";
 			$sql .= " ".($this->fk_project > 0 ? $this->db->escape($this->fk_project) : "null").",";
+			$sql .= " ".($this->fk_contract > 0 ? $this->db->escape($this->fk_contract) : "null").",";
 			$sql .= " ".(!isset($this->origin_email) ? 'NULL' : "'".$this->db->escape($this->origin_email)."'").",";
 			$sql .= " ".(!isset($this->fk_user_create) ? ($user->id > 0 ? $user->id : 'NULL') : ($this->fk_user_create > 0 ? $this->fk_user_create : 'NULL')).",";
 			$sql .= " ".($this->fk_user_assign > 0 ? $this->fk_user_assign : 'NULL').",";
@@ -635,6 +645,7 @@ class Ticket extends CommonObject
 		$sql .= " t.track_id,";
 		$sql .= " t.fk_soc,";
 		$sql .= " t.fk_project,";
+		$sql .= " t.fk_contract,";
 		$sql .= " t.origin_email,";
 		$sql .= " t.fk_user_create,";
 		$sql .= " t.fk_user_assign,";
@@ -687,6 +698,7 @@ class Ticket extends CommonObject
 				$this->fk_soc = $obj->fk_soc;
 				$this->socid = $obj->fk_soc; // for fetch_thirdparty() method
 				$this->fk_project = $obj->fk_project;
+				$this->fk_contract = $obj->fk_contract;
 				$this->origin_email = $obj->origin_email;
 				$this->fk_user_create = $obj->fk_user_create;
 				$this->fk_user_assign = $obj->fk_user_assign;
@@ -763,6 +775,7 @@ class Ticket extends CommonObject
 		$sql .= " t.track_id,";
 		$sql .= " t.fk_soc,";
 		$sql .= " t.fk_project,";
+		$sql .= " t.fk_contract,";
 		$sql .= " t.origin_email,";
 		$sql .= " t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
 		$sql .= " t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
@@ -782,8 +795,10 @@ class Ticket extends CommonObject
 		$sql .= " t.tms";
 		$sql .= ", type.label as type_label, category.label as category_label, severity.label as severity_label";
 		// Add fields for extrafields
-		foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
-			$sql .= ($extrafields->attributes[$this->table_element]['type'][$key] != 'separate' ? ",ef.".$key." as options_".$key : '');
+		if ($extrafields->attributes[$this->table_element]['count']> 0) {
+			foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
+				$sql .= ($extrafields->attributes[$this->table_element]['type'][$key] != 'separate' ? ",ef.".$key." as options_".$key : '');
+			}
 		}
 		$sql .= " FROM ".MAIN_DB_PREFIX."ticket as t";
 		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_type as type ON type.code=t.type_code";
@@ -792,8 +807,10 @@ class Ticket extends CommonObject
 		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=t.fk_soc";
 		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as uc ON uc.rowid=t.fk_user_create";
 		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as ua ON ua.rowid=t.fk_user_assign";
-		if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label'])) {
-			$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."ticket_extrafields as ef on (t.rowid = ef.fk_object)";
+		if ($extrafields->attributes[$this->table_element]['count']> 0) {
+			if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label'])) {
+				$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."ticket_extrafields as ef on (t.rowid = ef.fk_object)";
+			}
 		}
 		if (empty($user->rights->societe->client->voir) && !$user->socid) {
 			$sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -814,6 +831,8 @@ class Ticket extends CommonObject
 					} else {
 						$sql .= " AND ".$key.' = '.((int) $value);
 					}
+				} elseif ($key == 't.fk_contract') {
+					$sql .= " AND ".$key.' = '.((int) $value);
 				} else {
 					$sql .= " AND ".$key." LIKE '%".$this->db->escape($value)."%'";
 				}
@@ -851,6 +870,7 @@ class Ticket extends CommonObject
 					$line->track_id = $obj->track_id;
 					$line->fk_soc = $obj->fk_soc;
 					$line->fk_project = $obj->fk_project;
+					$line->fk_contract = $obj->fk_contract;
 					$line->origin_email = $obj->origin_email;
 
 					$line->fk_user_create = $obj->fk_user_create;
@@ -881,13 +901,14 @@ class Ticket extends CommonObject
 					$line->date_close = $this->db->jdate($obj->date_close);
 
 					// Extra fields
-					if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label'])) {
-						foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
-							$tmpkey = 'options_'.$key;
-							$line->{$tmpkey} = $obj->$tmpkey;
+					if ($extrafields->attributes[$this->table_element]['count']> 0) {
+						if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label'])) {
+							foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
+								$tmpkey = 'options_'.$key;
+								$line->{$tmpkey} = $obj->$tmpkey;
+							}
 						}
 					}
-
 					$this->lines[$i] = $line;
 					$i++;
 				}
@@ -934,6 +955,10 @@ class Ticket extends CommonObject
 			$this->fk_project = (int) $this->fk_project;
 		}
 
+		if (isset($this->fk_contract)) {
+			$this->fk_contract = (int) $this->fk_contract;
+		}
+
 		if (isset($this->origin_email)) {
 			$this->origin_email = trim($this->origin_email);
 		}
@@ -995,6 +1020,7 @@ class Ticket extends CommonObject
 		$sql .= " track_id=".(isset($this->track_id) ? "'".$this->db->escape($this->track_id)."'" : "null").",";
 		$sql .= " fk_soc=".(isset($this->fk_soc) ? "'".$this->db->escape($this->fk_soc)."'" : "null").",";
 		$sql .= " fk_project=".(isset($this->fk_project) ? "'".$this->db->escape($this->fk_project)."'" : "null").",";
+		$sql .= " fk_contract=".(isset($this->fk_contract) ? "'".$this->db->escape($this->fk_contract)."'" : "null").",";
 		$sql .= " origin_email=".(isset($this->origin_email) ? "'".$this->db->escape($this->origin_email)."'" : "null").",";
 		$sql .= " fk_user_create=".(isset($this->fk_user_create) ? $this->fk_user_create : "null").",";
 		$sql .= " fk_user_assign=".(isset($this->fk_user_assign) ? $this->fk_user_assign : "null").",";
@@ -2048,17 +2074,19 @@ class Ticket extends CommonObject
 	 */
 	public function setContract($contractid)
 	{
-		if (!$this->table_element) {
-			dol_syslog(get_class($this)."::setContract was called on objet with property table_element not defined", LOG_ERR);
-			return -1;
-		}
-
-		$result = $this->add_object_linked('contrat', $contractid);
-		if ($result) {
-			$this->fk_contract = $contractid;
-			return 1;
+		if ($this->id) {
+			$sql = "UPDATE ".MAIN_DB_PREFIX."ticket";
+			$sql .= " SET fk_contract = ".($contractid > 0 ? $contractid : "null");
+			$sql .= " WHERE rowid = ".((int) $this->id);
+			dol_syslog(get_class($this).'::setContract sql='.$sql);
+			$resql = $this->db->query($sql);
+			print $sql;
+			if ($resql) {
+				return 1;
+			} else {
+				return -1;
+			}
 		} else {
-			dol_print_error($this->db);
 			return -1;
 		}
 	}

+ 3 - 0
htdocs/ticket/list.php

@@ -681,6 +681,9 @@ if ($search_societe) {
 if ($projectid > 0) {
 	$param .= '&projectid='.urlencode($projectid);
 }
+if ($contractid > 0) {
+	$param .= '&contractid='.urlencode($contractid);
+}
 if ($search_date_start) {
 	$tmparray = dol_getdate($search_date_start);
 	$param .= '&search_date_startday='.urlencode($tmparray['mday']);