Skip to content
Snippets Groups Projects
project.class.php 61.1 KiB
Newer Older
Benoit Mortier's avatar
 
Benoit Mortier committed
<?php
/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
 * Copyright (C) 2005-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
 * Copyright (C) 2005-2010 Regis Houssin        <regis.houssin@capnetworks.com>
Florian Henry's avatar
Florian Henry committed
 * Copyright (C) 2013	   Florian Henry        <florian.henry@open-concept.pro>
Marcos García de La Fuente's avatar
Marcos García de La Fuente committed
 * Copyright (C) 2014-2015 Marcos García        <marcosgdf@gmail.com>
Rodolphe Quiedeville's avatar
.
Rodolphe Quiedeville committed
 *
 * 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
Rodolphe Quiedeville's avatar
.
Rodolphe Quiedeville committed
 * (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/>.
Rodolphe Quiedeville's avatar
.
Rodolphe Quiedeville committed
 */

 * 		\file       htdocs/projet/class/project.class.php
 * 		\ingroup    projet
 * 		\brief      File of class to manage projects
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
 *	Class to manage projects
class Project extends CommonObject

    public $element = 'project';    //!< Id that identify managed objects
    public $table_element = 'projet';  //!< Name of table without prefix where object is stored
    public $table_element_line = 'projet_task';
    public $fk_element = 'fk_projet';
    protected $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    public $picto = 'projectpub';
    
    var $description;
	/**
	 * @var string
	 * @deprecated
	 * @see title
	 */
	public $titre;
    var $title;
    var $date_start;
    var $date_end;
    var $socid;             // To store id of thirdparty
    var $thirdparty_name;   // To store name of thirdparty (defined only in some cases)
    var $user_author_id;    //!< Id of project creator. Not defined if shared project.
	var $user_close_id;
    var $public;      //!< Tell if this is a public or private project
    var $budget_amount;

    var $statuts_short;
Laurent Destailleur's avatar
Laurent Destailleur committed
    var $statut;			// 0=draft, 1=opened, 2=closed
    var $opp_status;		// opportunity status, into table llx_c_lead_status
	var $opp_percent;		// opportunity probability
    var $weekWorkLoad;			// Used to store workload details of a projet
    var $weekWorkLoadPerTask;	// Used to store workload details of tasks of a projet

	/**
	 * @var int Creation date
	 * @deprecated
	 * @see date_c
	 */
	public $datec;
	/**
	 * @var int Creation date
	 */
	public $date_c;
	/**
	 * @var int Modification date
	 * @deprecated
	 * @see date_m
	 */
	public $datem;
	/**
	 * @var int Modification date
	 */
	public $date_m;

    /**
     *  Constructor
     *
Laurent Destailleur's avatar
Laurent Destailleur committed
     *  @param      DoliDB		$db      Database handler
Regis Houssin's avatar
Regis Houssin committed
    function __construct($db)
Regis Houssin's avatar
Regis Houssin committed
        $this->db = $db;
        $this->statuts_short = array(0 => 'Draft', 1 => 'Opened', 2 => 'Closed');
        $this->statuts_long = array(0 => 'Draft', 1 => 'Opened', 2 => 'Closed');
    }

    /**
     *    Create a project into database
     *
     *    @param    User	$user       	User making creation
     *    @param	int		$notrigger		Disable triggers
     *    @return   int         			<0 if KO, id of created project if OK
     */
    function create($user, $notrigger=0)
    {
        global $conf, $langs;

        $error = 0;
        $ret = 0;

Laurent Destailleur's avatar
Laurent Destailleur committed
        $now=dol_now();

        // Check parameters
        if (!trim($this->ref))
        {
            $this->error = 'ErrorFieldsRequired';
            dol_syslog(get_class($this)."::create error -1 ref null", LOG_ERR);
            return -1;
        }

        $this->db->begin();

        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "projet (";
        $sql.= "ref";
        $sql.= ", title";
        $sql.= ", description";
        $sql.= ", fk_soc";
        $sql.= ", fk_user_creat";
        $sql.= ", fk_statut";
        $sql.= ", fk_opp_status";
        $sql.= ", public";
        $sql.= ", datec";
        $sql.= ", dateo";
        $sql.= ", datee";
        $sql.= ", opp_amount";
        $sql.= ", budget_amount";
Regis Houssin's avatar
Regis Houssin committed
        $sql.= ", entity";
        $sql.= ") VALUES (";
        $sql.= "'" . $this->db->escape($this->ref) . "'";
        $sql.= ", '" . $this->db->escape($this->title) . "'";
        $sql.= ", '" . $this->db->escape($this->description) . "'";
        $sql.= ", " . ($this->socid > 0 ? $this->socid : "null");
        $sql.= ", " . $user->id;
Laurent Destailleur's avatar
Laurent Destailleur committed
        $sql.= ", ".(is_numeric($this->statut) ? $this->statut : '0');
        $sql.= ", ".(is_numeric($this->opp_status) ? $this->opp_status : 'NULL');
        $sql.= ", ".(is_numeric($this->opp_percent) ? $this->opp_percent : 'NULL');
        $sql.= ", " . ($this->public ? 1 : 0);
Laurent Destailleur's avatar
Laurent Destailleur committed
        $sql.= ", '".$this->db->idate($now)."'";
        $sql.= ", " . ($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : 'null');
        $sql.= ", " . ($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : 'null');
        $sql.= ", " . (strcmp($this->opp_amount,'') ? price2num($this->opp_amount) : 'null');
        $sql.= ", " . (strcmp($this->budget_amount,'') ? price2num($this->budget_amount) : 'null');
Regis Houssin's avatar
Regis Houssin committed
        $sql.= ", ".$conf->entity;
        dol_syslog(get_class($this)."::create", LOG_DEBUG);
        $resql = $this->db->query($sql);
        if ($resql)
        {
            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "projet");
            $ret = $this->id;

            if (!$notrigger)
            {
                // Call trigger
                $result=$this->call_trigger('PROJECT_CREATE',$user);
                if ($result < 0) { $error++; }
                // End call triggers
            }
        }
        else
        {
            $this->error = $this->db->lasterror();
            $this->errno = $this->db->lasterrno();
            $error++;
        }
        // Update extrafield
        if (!$error) {
        	if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
        	{
        		$result=$this->insertExtraFields();
        		if ($result < 0)
        		{
        			$error++;
        		}
        	}
        }

        if (!$error && !empty($conf->global->MAIN_DISABLEDRAFTSTATUS))
        {
            $res = $this->setValid($user);
        if (!$error)
        {
        }
    }

    /**
     * Update a project
     *
     * @param  User		$user       User object of making update
     * @param  int		$notrigger  1=Disable all triggers
     * @return int
     */
    function update($user, $notrigger=0)
    {
        global $langs, $conf;
        // Clean parameters
        $this->title = trim($this->title);
        $this->description = trim($this->description);
Laurent Destailleur's avatar
Laurent Destailleur committed
		if ($this->opp_amount < 0) $this->opp_amount='';
		if ($this->opp_percent < 0) $this->opp_percent='';

        if (dol_strlen(trim($this->ref)) > 0)
        {
            $this->db->begin();
            $sql = "UPDATE " . MAIN_DB_PREFIX . "projet SET";
Charles Benke's avatar
Charles Benke committed
            $sql.= " ref='" . $this->db->escape($this->ref) . "'";
            $sql.= ", title = '" . $this->db->escape($this->title) . "'";
            $sql.= ", description = '" . $this->db->escape($this->description) . "'";
            $sql.= ", fk_soc = " . ($this->socid > 0 ? $this->socid : "null");
            $sql.= ", fk_statut = " . $this->statut;
            $sql.= ", fk_opp_status = " . ((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status : 'null');
			$sql.= ", opp_percent = " . ((is_numeric($this->opp_percent) && $this->opp_percent != '') ? $this->opp_percent : 'null');
            $sql.= ", public = " . ($this->public ? 1 : 0);
            $sql.= ", datec=" . ($this->date_c != '' ? "'".$this->db->idate($this->date_c)."'" : 'null');
            $sql.= ", dateo=" . ($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : 'null');
            $sql.= ", datee=" . ($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : 'null');
            $sql.= ", date_close=" . ($this->date_close != '' ? "'".$this->db->idate($this->date_close)."'" : 'null');
            $sql.= ", fk_user_close=" . ($this->fk_user_close > 0 ? $this->fk_user_close : "null");
            $sql.= ", opp_amount = " . (strcmp($this->opp_amount, '') ? price2num($this->opp_amount) : "null");
            $sql.= ", budget_amount = " . (strcmp($this->budget_amount, '')  ? price2num($this->budget_amount) : "null");
            $sql.= " WHERE rowid = " . $this->id;

Laurent Destailleur's avatar
Laurent Destailleur committed
            dol_syslog(get_class($this)."::update", LOG_DEBUG);
            $resql=$this->db->query($sql);
            if ($resql)
            {
                if (!$notrigger)
                {
                    // Call trigger
                    $result=$this->call_trigger('PROJECT_MODIFY',$user);
                    if ($result < 0) { $error++; }
                    // End call triggers
                }
                //Update extrafield
                if (!$error) {
                	if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
                	{
                		$result=$this->insertExtraFields();
                		if ($result < 0)
                		{
                			$error++;
                		}
                	}
                }
                if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref))
                {
                	// We remove directory
                	if ($conf->projet->dir_output)
                	{
                		$olddir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref);
                		$newdir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($this->ref);
                		if (file_exists($olddir))
                		{
							include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
							$res=dol_move($olddir, $newdir);
							if (! $res)
Laurent Destailleur's avatar
Laurent Destailleur committed
							    $langs->load("errors");
								$this->error=$langs->trans('ErrorFailToRenameDir',$olddir,$newdir);
                if (! $error )
                {
                    $this->db->commit();
                    $result = 1;
                }
                else
                    $this->db->rollback();
                    $result = -1;
                }
                $this->error = $this->db->lasterror();
                $this->errors[] = $this->error;
                $this->db->rollback();
Laurent Destailleur's avatar
Laurent Destailleur committed
                dol_syslog(get_class($this)."::update error -2 " . $this->error, LOG_ERR);
Laurent Destailleur's avatar
Laurent Destailleur committed
            dol_syslog(get_class($this)."::update ref null");
            $result = -1;
        }

        return $result;
    }

    /**
     * 	Get object and lines from database
     *
     * 	@param      int		$id       	Id of object to load
     * 	@param		string	$ref		Ref of project
     * 	@return     int      		   	>0 if OK, 0 if not found, <0 if KO
     */
    function fetch($id, $ref='')
    {
        if (empty($id) && empty($ref)) return -1;

        $sql = "SELECT rowid, ref, title, description, public, datec, opp_amount, budget_amount,";
        $sql.= " tms, dateo, datee, date_close, fk_soc, fk_user_creat, fk_user_close, fk_statut, fk_opp_status, opp_percent, note_private, note_public, model_pdf";
        $sql.= " FROM " . MAIN_DB_PREFIX . "projet";
        if (! empty($id))
        {
        	$sql.= " WHERE rowid=".$id;
        }
        else if (! empty($ref))
Laurent Destailleur's avatar
Laurent Destailleur committed
        	$sql.= " WHERE ref='".$this->db->escape($ref)."'";
        	$sql.= " AND entity IN (".getEntity('project',1).")";
        dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
        $resql = $this->db->query($sql);
        if ($resql)
        {
            if ($this->db->num_rows($resql))
            {
                $obj = $this->db->fetch_object($resql);

                $this->id = $obj->rowid;
                $this->ref = $obj->ref;
                $this->title = $obj->title;
                $this->titre = $obj->title; // TODO deprecated
                $this->description = $obj->description;
                $this->date_c = $this->db->jdate($obj->datec);
                $this->datec = $this->db->jdate($obj->datec); // TODO deprecated
                $this->date_m = $this->db->jdate($obj->tms);
                $this->datem = $this->db->jdate($obj->tms);  // TODO deprecated
                $this->date_start = $this->db->jdate($obj->dateo);
                $this->date_end = $this->db->jdate($obj->datee);
                $this->date_close = $this->db->jdate($obj->date_close);
                $this->note_private = $obj->note_private;
                $this->note_public = $obj->note_public;
                $this->socid = $obj->fk_soc;
                $this->user_author_id = $obj->fk_user_creat;
                $this->user_close_id = $obj->fk_user_close;
                $this->public = $obj->public;
                $this->statut = $obj->fk_statut;
                $this->opp_status = $obj->fk_opp_status;
                $this->opp_amount	= $obj->opp_amount;
                $this->opp_percent	= $obj->opp_percent;
                $this->budget_amount	= $obj->budget_amount;
                $this->modelpdf	= $obj->model_pdf;

                $this->db->free($resql);

                return 1;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            $this->error = $this->db->lasterror();
            return -1;
        }
    }

    /**
     * 	Return list of projects
     *
     * 	@param		int		$socid		To filter on a particular third party
     * 	@return		array				List of projects
     */
    function liste_array($socid='')
    {
        global $conf;

        $projects = array();

        $sql = "SELECT rowid, title";
        $sql.= " FROM " . MAIN_DB_PREFIX . "projet";
        $sql.= " WHERE entity = " . $conf->entity;
        if (! empty($socid)) $sql.= " AND fk_soc = " . $socid;

        $resql = $this->db->query($sql);
        if ($resql)
        {
            $nump = $this->db->num_rows($resql);

            if ($nump)
            {
                $i = 0;
                while ($i < $nump)
                {
                    $obj = $this->db->fetch_object($resql);

                    $projects[$obj->rowid] = $obj->title;
                    $i++;
                }
            }
            return $projects;
        }
        else
        {
            print $this->db->lasterror();
        }
    }

    /**
     * 	Return list of elements for type, linked to project
     * 	@param		string		$type			'propal','order','invoice','order_supplier','invoice_supplier',...
     * 	@param		string		$tablename		name of table associated of the type
     * 	@param		string		$datefieldname	name of date field for filter
     *  @param		string		$dates			Start date (ex 00:00:00)
     *  @param		string		$datee			End date (ex 23:59:59)
     * 	@return		mixed						Array list of object ids linked to project, < 0 or string if error
    function get_element_list($type, $tablename, $datefieldname='', $dates='', $datee='')
    {
        $elements = array();
        if ($this->id <= 0) return $elements;
            $sql = "SELECT id as rowid FROM " . MAIN_DB_PREFIX . "actioncomm WHERE fk_project=" . $this->id;
            $sql = "SELECT ed.rowid FROM " . MAIN_DB_PREFIX . "expensereport as e, " . MAIN_DB_PREFIX . "expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND ed.fk_projet=" . $this->id;
			$sql = "SELECT DISTINCT pt.rowid FROM " . MAIN_DB_PREFIX . "projet_task as pt, " . MAIN_DB_PREFIX . "projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet=" . $this->id;
		}
		elseif ($type == 'project_task_time')	// Case we want to duplicate line foreach user
		{
			$sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM " . MAIN_DB_PREFIX . "projet_task as pt, " . MAIN_DB_PREFIX . "projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet=" . $this->id;
        else
		{
            $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . $tablename." WHERE fk_projet=" . $this->id;
		}

		if ($dates > 0)
		{
			if (empty($datefieldname) && ! empty($this->table_element_date)) $datefieldname=$this->table_element_date;
			if (empty($datefieldname)) return 'Error this object has no date field defined';
			$sql.=" AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)";
		}
    	if ($datee > 0)
		{
			if (empty($datefieldname) && ! empty($this->table_element_date)) $datefieldname=$this->table_element_date;
			if (empty($datefieldname)) return 'Error this object has no date field defined';
			$sql.=" AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)";

        //print $sql;
        dol_syslog(get_class($this)."::get_element_list", LOG_DEBUG);
        $result = $this->db->query($sql);
        if ($result)
        {
            $nump = $this->db->num_rows($result);
            if ($nump)
            {
                $i = 0;
                while ($i < $nump)
                {
                    $obj = $this->db->fetch_object($result);

                    $elements[$i] = $obj->rowid.(empty($obj->fk_user)?'':'_'.$obj->fk_user);

                    $i++;
                }
                $this->db->free($result);

                /* Return array */
                return $elements;
            }
        }
        else
        {
            dol_print_error($this->db);
        }
    }

    /**
     *    Delete a project from database
     *
     *    @param       User		$user            User
     *    @param       int		$notrigger       Disable triggers
     *    @return      int       			      <0 if KO, 0 if not possible, >0 if OK
     */
    function delete($user, $notrigger=0)
    {
        global $langs, $conf;
        require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';

        $error = 0;

        $this->db->begin();

        if (!$error)
        {
            // Delete linked contacts
            $res = $this->delete_linked_contact();
            if ($res < 0)
            {
                $this->error = 'ErrorFailToDeleteLinkedContact';
                //$error++;
                $this->db->rollback();
                return 0;
            }
        }

        // Set fk_projet into elements to null
        $listoftables=array(
        		'facture'=>'fk_projet','propal'=>'fk_projet','commande'=>'fk_projet','facture_fourn'=>'fk_projet','commande_fournisseur'=>'fk_projet',
        		'expensereport_det'=>'fk_projet','contrat'=>'fk_projet','fichinter'=>'fk_projet','don'=>'fk_projet'
        		);
        foreach($listoftables as $key => $value)
        {
   	        $sql = "UPDATE " . MAIN_DB_PREFIX . $key . " SET ".$value." = NULL where ".$value." = ". $this->id;
	        $resql = $this->db->query($sql);
	        if (!$resql)
	        {
	        	$this->errors[] = $this->db->lasterror();
	        	$error++;
	        	break;
	        }
        }
	        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "projet_task_time";
	        $sql.= " WHERE fk_task IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "projet_task WHERE fk_projet=" . $this->id . ")";
	        $resql = $this->db->query($sql);
	        if (!$resql)
	        {
	        	$this->errors[] = $this->db->lasterror();
	        	$error++;
	        }
	        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "projet_task_extrafields";
	        $sql.= " WHERE fk_object IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "projet_task WHERE fk_projet=" . $this->id . ")";
	        $resql = $this->db->query($sql);
	        if (!$resql)
	        {
	        	$this->errors[] = $this->db->lasterror();
	        	$error++;
	        }
	        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "projet_task";
	        $sql.= " WHERE fk_projet=" . $this->id;

	        $resql = $this->db->query($sql);
	        if (!$resql)
	        {
	        	$this->errors[] = $this->db->lasterror();
	        	$error++;
	        }
        // Delete project
        if (! $error)
        {
	        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "projet";
	        $sql.= " WHERE rowid=" . $this->id;
	        $resql = $this->db->query($sql);
	        if (!$resql)
	        {
	        	$this->errors[] = $langs->trans("CantRemoveProject");
	        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "projet_extrafields";
	        $sql.= " WHERE fk_object=" . $this->id;

	        $resql = $this->db->query($sql);
	        if (! $resql)
	        {
	        	$this->errors[] = $this->db->lasterror();
	        	$error++;
	        }
        if (empty($error))
        {
            // We remove directory
            $projectref = dol_sanitizeFileName($this->ref);
            if ($conf->projet->dir_output)
            {
                $dir = $conf->projet->dir_output . "/" . $projectref;
                if (file_exists($dir))
                {
Florian Henry's avatar
Florian Henry committed
                    $res = @dol_delete_dir_recursive($dir);
                    if (!$res)
                    {
                        $this->errors[] = 'ErrorFailToDeleteDir';
                        $error++;
                // Call trigger
                $result=$this->call_trigger('PROJECT_DELETE',$user);
                    $error++;
                }
                // End call triggers
            }
            $this->db->commit();
            return 1;
        }
        else
       {
        	foreach ( $this->errors as $errmsg )
        	{
				dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
				$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
			}
            dol_syslog(get_class($this) . "::delete " . $this->error, LOG_ERR);
            $this->db->rollback();
            return -1;
        }
    }
    /**
     * 		Validate a project
     *
     * 		@param		User	$user		   User that validate
     *      @param      int     $notrigger     1=Disable triggers
     * 		@return		int					   <0 if KO, >0 if OK
    function setValid($user, $notrigger=0)
    {
        global $langs, $conf;

        if ($this->statut != 1)
        {
            // Check parameters
            if (preg_match('/^'.preg_quote($langs->trans("CopyOf").' ').'/', $this->title))
            {
                $this->error=$langs->trans("ErrorFieldFormat",$langs->transnoentities("Label")).'. '.$langs->trans('RemoveString',$langs->transnoentitiesnoconv("CopyOf"));
                return -1;
            }
            
            $this->db->begin();

            $sql = "UPDATE " . MAIN_DB_PREFIX . "projet";
            $sql.= " SET fk_statut = 1";
            $sql.= " WHERE rowid = " . $this->id;
            $sql.= " AND entity = " . $conf->entity;

            dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
            $resql = $this->db->query($sql);
            if ($resql)
            {
                if (empty($notrigger))
                {
                    $result=$this->call_trigger('PROJECT_VALIDATE',$user);
                    if ($result < 0) { $error++; }
                    // End call triggers
                }
                
                if (!$error)
                {
                	$this->statut=1;
                	$this->db->commit();
                    return 1;
                }
                else
                {
                    $this->db->rollback();
                    $this->error = join(',', $this->errors);
                    dol_syslog(get_class($this)."::setValid " . $this->error, LOG_ERR);
                    return -1;
                }
            }
            else
            {
                $this->db->rollback();
                $this->error = $this->db->lasterror();
                return -1;
            }
        }
    }

    /**
     * 		Close a project
     *
     * 		@param		User	$user		User that close project
     * 		@return		int					<0 if KO, >0 if OK
     */
    function setClose($user)
    {
        global $langs, $conf;

        if ($this->statut != 2)
        {
            $this->db->begin();

            $sql = "UPDATE " . MAIN_DB_PREFIX . "projet";
            $sql.= " SET fk_statut = 2, fk_user_close = ".$user->id.", date_close = '".$this->db->idate($now)."'";
            $sql.= " WHERE rowid = " . $this->id;
            $sql.= " AND entity = " . $conf->entity;
            $sql.= " AND fk_statut = 1";

            if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
            {
            	// TODO What to do if fk_opp_status is not code 'WON' or 'LOST'
            dol_syslog(get_class($this)."::setClose", LOG_DEBUG);
            $resql = $this->db->query($sql);
            if ($resql)
            {
                // Call trigger
                $result=$this->call_trigger('PROJECT_CLOSE',$user);
                if ($result < 0) { $error++; }
                // End call triggers
                    $this->db->commit();
                    return 1;
                }
                else
                {
                    $this->db->rollback();
                    $this->error = join(',', $this->errors);
                    dol_syslog(get_class($this)."::setClose " . $this->error, LOG_ERR);
                    return -1;
                }
            }
            else
            {
                $this->db->rollback();
                $this->error = $this->db->lasterror();
                return -1;
            }
        }
    }

    /**
     *  Return status label of object
     *
     *  @param  int			$mode       0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
     * 	@return string      			Label
     */
    function getLibStatut($mode=0)
    {
        return $this->LibStatut($this->statut, $mode);
    }

    /**
     *  Renvoi status label for a status
     *
     *  @param	int		$statut     id statut
     *  @param  int		$mode       0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
     * 	@return string				Label
     */
    function LibStatut($statut, $mode=0)
    {
        global $langs;

        if ($mode == 0)
        {
            return $langs->trans($this->statuts_long[$statut]);
        }
        if ($mode == 1)
        {
            return $langs->trans($this->statuts_short[$statut]);
        }
        if ($mode == 2)
        {
            if ($statut == 0)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut0') . ' ' . $langs->trans($this->statuts_short[$statut]);
            if ($statut == 1)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut4') . ' ' . $langs->trans($this->statuts_short[$statut]);
            if ($statut == 2)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut6') . ' ' . $langs->trans($this->statuts_short[$statut]);
        }
        if ($mode == 3)
        {
            if ($statut == 0)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut0');
            if ($statut == 1)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut4');
            if ($statut == 2)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut6');
        }
        if ($mode == 4)
        {
            if ($statut == 0)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut0') . ' ' . $langs->trans($this->statuts_long[$statut]);
            if ($statut == 1)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut4') . ' ' . $langs->trans($this->statuts_long[$statut]);
            if ($statut == 2)
                return img_picto($langs->trans($this->statuts_long[$statut]), 'statut6') . ' ' . $langs->trans($this->statuts_long[$statut]);
        }
        if ($mode == 5)
        {
            if ($statut == 0)
                return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_long[$statut]), 'statut0');
            if ($statut == 1)
                return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_long[$statut]), 'statut4');
            if ($statut == 2)
                return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_long[$statut]), 'statut6');
     * 	Return clicable name (with picto eventually)
     * 	@param	int		$withpicto		0=No picto, 1=Include picto into link, 2=Only picto
     * 	@param	string	$option			Variant ('', 'nolink')
     * 	@param	int		$addlabel		0=Default, 1=Add label into string, >1=Add first chars into string
     *  @param	string	$moreinpopup	Text to add into popup
     *  @param	string	$sep			Separator between ref and label if option addlabel is set
Laurent Destailleur's avatar
Laurent Destailleur committed
     *  @param	int   	$notooltip		1=Disable tooltip
     * 	@return	string					Chaine avec URL
     */
Laurent Destailleur's avatar
Laurent Destailleur committed
    function getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='', $sep=' - ', $notooltip=0)
Laurent Destailleur's avatar
Laurent Destailleur committed
        global $conf, $langs, $user;
Laurent Destailleur's avatar
Laurent Destailleur committed
        if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
        
        $result = '';
        $label='';
        if ($option != 'nolink') $label = '<u>' . $langs->trans("ShowProject") . '</u>';
Frédéric France's avatar
Frédéric France committed
        if (! empty($this->ref))
            $label .= ($label?'<br>':'').'<b>' . $langs->trans('Ref') . ': </b>' . $this->ref;	// The space must be after the : to not being explode when showing the title in img_picto
Frédéric France's avatar
Frédéric France committed
        if (! empty($this->title))
            $label .= ($label?'<br>':'').'<b>' . $langs->trans('Label') . ': </b>' . $this->title;	// The space must be after the : to not being explode when showing the title in img_picto
        if (! empty($this->thirdparty_name))
            $label .= ($label?'<br>':'').'<b>' . $langs->trans('ThirdParty') . ': </b>' . $this->thirdparty_name;	// The space must be after the : to not being explode when showing the title in img_picto
        if (! empty($this->dateo))
            $label .= ($label?'<br>':'').'<b>' . $langs->trans('DateStart') . ': </b>' . dol_print_date($this->dateo, 'day');	// The space must be after the : to not being explode when showing the title in img_picto
        if (! empty($this->datee))
            $label .= ($label?'<br>':'').'<b>' . $langs->trans('DateEnd') . ': </b>' . dol_print_date($this->datee, 'day');	// The space must be after the : to not being explode when showing the title in img_picto
        if ($moreinpopup) $label.='<br>'.$moreinpopup;
florian HENRY's avatar
florian HENRY committed
        if ($option != 'nolink')
            if (preg_match('/\.php$/',$option)) {
Laurent Destailleur's avatar
Laurent Destailleur committed
                $url = dol_buildpath($option,1) . '?id=' . $this->id;
Laurent Destailleur's avatar
Laurent Destailleur committed
                $url = DOL_URL_ROOT . '/projet/tasks.php?id=' . $this->id;
Laurent Destailleur's avatar
Laurent Destailleur committed
                $url = DOL_URL_ROOT . '/projet/card.php?id=' . $this->id;
            }
        }
        
        $linkclose='';
        if (empty($notooltip) && $user->rights->propal->lire)
        {
            if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
            {
                $label=$langs->trans("ShowProject");
                $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
Laurent Destailleur's avatar
Laurent Destailleur committed
            $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
            $linkclose.=' class="classfortooltip"';
        }

        $picto = 'projectpub';
        if (!$this->public) $picto = 'project';

Laurent Destailleur's avatar
Laurent Destailleur committed
        $linkstart = '<a href="'.$url.'"';
        $linkstart.=$linkclose.'>';
        $linkend='</a>';
        
        if ($withpicto) $result.=($linkstart . img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1) . $linkend);
        if ($withpicto && $withpicto != 2) $result.=' ';
Laurent Destailleur's avatar
Laurent Destailleur committed
        if ($withpicto != 2) $result.=$linkstart . $this->ref . $linkend . (($addlabel && $this->title) ? $sep . dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) : '');
        return $result;
    }

    /**
Laurent Destailleur's avatar
Laurent Destailleur committed
     *  Initialise an instance with random values.
     *  Used to build previews or test instances.
     * 	id must be 0 if object instance is a specimen.
Laurent Destailleur's avatar
Laurent Destailleur committed
     *
     *  @return	void
     */
    function initAsSpecimen()
    {
        global $user, $langs, $conf;

        $now=dol_now();
        // Initialise parameters
        $this->id = 0;
        $this->ref = 'SPECIMEN';
        $this->specimen = 1;
        $this->date_c = $now;
        $this->date_m = $now;
        $this->date_start = $now;
        $this->date_end = $now + (3600 * 24 * 365);
        $this->note_public = 'SPECIMEN';
		$this->fk_ele = 20000;
        $this->opp_amount = 20000;
        $this->budget_amount = 10000;

        $xnbp = 0;
        while ($xnbp < $nbp)
        {
            $line = new Task($this->db);
            $line->fk_project = 0;
            $line->label = $langs->trans("Label") . " " . $xnbp;
            $line->description = $langs->trans("Description") . " " . $xnbp;

            $this->lines[]=$line;