<?php
/* Copyright (C) 2008-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
 * Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
 * Copyright (C) 2014       Marcos García       <marcosgdf@gmail.com>
 * Copyright (C) 2018       Charlène Benke		<charlène@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/projet/class/task.class.php
 *      \ingroup    project
 *      \brief      This file is a CRUD class file for Task (Create/Read/Update/Delete)
 */

require_once DOL_DOCUMENT_ROOT.'/projet/class/Task.class.php';


/**
 * 	Class to manage tasks
 */
class Taskschedule extends Task
{

	var $timeplanned_min_date;
	var $timeplanned_max_date;
	var $timeplanned_total_duration;
	var $timeplanned_total_amount;
	var $timeplanned_nblinesnull;
	var $timeplanned_nblines;
	// For detail of lines of timespent record, there is the property ->lines in common

	// Var used to call method addTimeSpent(). Bad practice.
	var $timeplanned_id;
	var $timeplanned_duration;
	var $timeplanned_old_duration;
	var $timeplanned_date;
	var $timeplanned_datehour;		// More accurate start date (same than timespent_date but includes hours, minutes and seconds)
	var $timeplanned_withhour;		// 1 = we entered also start hours for timesheet line
	var $timeplanned_fk_user;
	var $timeplanned_note;


	/**
	 *  Constructor
	 *
	 *  @param      DoliDB		$db      Database handler
	 */
	function __construct($db)
	{
		$this->db = $db;
	}


	/**
	 *	Return nb of time spent
	 *
	 *	@return	int		<0 if KO, 0 if no children, >0 if OK
	 */
	function hasTimePlanned()
	{
		$error=0;
		$ret=0;

		$sql = "SELECT COUNT(*) as nb";
		$sql.= " FROM ".MAIN_DB_PREFIX."projet_task_schedule";
		$sql.= " WHERE fk_task=".$this->id;

		dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG);
		$resql = $this->db->query($sql);
		if (! $resql) { 
			$error++; 
			$this->errors[]="Error ".$this->db->lasterror(); 
		} else {
			$obj=$this->db->fetch_object($resql);
			if ($obj) $ret=$obj->nb;
			$this->db->free($resql);
		}

		if (! $error)
			return $ret;
		else
			return -1;
	}

	/**
	 *  Add time spent
	 *
	 *  @param	User	$user           User object
	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
	 *  @return	int                     <=0 if KO, >0 if OK
	 */
	function addTimePlanned($user, $notrigger=0)
	{
		global $conf,$langs;

		dol_syslog(get_class($this)."::addTimePlanned", LOG_DEBUG);

		$ret = 0;

		// Check parameters
		if (! is_object($user)) {
			dol_print_error('',"Method addTimeChedule was called with wrong parameter user");
			return -1;
		}

		// Clean parameters
		if (isset($this->timeplanned_note)) 
			$this->timeplanned_note = trim($this->timeplanned_note);
		if (empty($this->timeplanned_datehour)) 
			$this->timeplanned_datehour = $this->timeplanned_date;

		$this->db->begin();

		$sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_schedule (";
		$sql.= "fk_task";
		$sql.= ", task_date";
		$sql.= ", task_datehour";
		$sql.= ", task_date_withhour";
		$sql.= ", task_duration";
		$sql.= ", fk_user";
		$sql.= ", note";
		$sql.= ") VALUES (";
		$sql.= $this->id;
		$sql.= ", '".$this->db->idate($this->timeplanned_date)."'";
		$sql.= ", '".$this->db->idate($this->timeplanned_datehour)."'";
		$sql.= ", ".(empty($this->timeplanned_withhour)?0:1);
		$sql.= ", ".$this->timeplanned_duration;
		$sql.= ", ".$this->timeplanned_fk_user;
		$sql.= ", ".(isset($this->timeplanned_note)?"'".$this->db->escape($this->timeplanned_note)."'":"null");
		$sql.= ")";

		$resql=$this->db->query($sql);
		if ($resql) {
			$tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_schedule");
			$ret = $tasktime_id;
			$this->timeplanned_id = $ret;

			if (! $notrigger) {
				// Call trigger
				$result=$this->call_trigger('TASK_TIMECHEDULE_CREATE',$user);
				if ($result < 0) { $ret=-1; }
				// End call triggers
			}
		} else {
			$this->error=$this->db->lasterror();
			$ret = -1;
		}

		if ($ret > 0) {
			$sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_schedule";
			$sql.= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->timeplanned_fk_user.")";	// set average hour rate of user
			$sql.= " WHERE rowid = ".$tasktime_id;

			dol_syslog(get_class($this)."::addTimePlanned", LOG_DEBUG);
			if (! $this->db->query($sql) ) {
				$this->error=$this->db->lasterror();
				$ret = -2;
			}
		}

		if ($ret >0) {
			$this->db->commit();
		} else {
			$this->db->rollback();
		}
		return $ret;
	}


	/**
	 *  Calculate quantity and value of time consumed using the thm (hourly amount value of work for user entering time)
	 *
	 *	@param		User		$fuser		Filter on a dedicated user
	 *  @param		string		$dates		Start date (ex 00:00:00)
	 *  @param		string		$datee		End date (ex 23:59:59)
	 *  @return 	array	        		Array of info for task array('amount','nbseconds','nblinesnull')
	 */
	function getSumOfAmountSchedule($fuser='', $dates='', $datee='')
	{
		global $langs;

		if (empty($id)) $id=$this->id;

		$result=array();

		$sql = "SELECT";
		$sql.= " SUM(t.task_duration) as nbseconds,";
		$sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull";
		$sql.= " FROM ".MAIN_DB_PREFIX."projet_task_schedule as t";
		$sql.= " WHERE t.fk_task = ".$id;
		if (is_object($fuser) && $fuser->id > 0) {
			$sql.=" AND fk_user = ".$fuser->id;
		}
		if ($dates > 0) {
			$datefieldname="task_datehour";
			$sql.=" AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)";
		}
		if ($datee > 0) {
			$datefieldname="task_datehour";
			$sql.=" AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)";
		}
		//print $sql;

		dol_syslog(get_class($this)."::getSumOfAmountSchedule", LOG_DEBUG);
		$resql=$this->db->query($sql);
		if ($resql) {
			$obj = $this->db->fetch_object($resql);

			$result['amount'] = $obj->amount;
			$result['nbseconds'] = $obj->nbseconds;
			$result['nblinesnull'] = $obj->nblinesnull;

			$this->db->free($resql);
			return $result;
		} else {
			dol_print_error($this->db);
			return $result;
		}
	}

	/**
	 *  Load one record of time spent
	 *
	 *  @param	int		$id 	Id object
	 *  @return int		        <0 if KO, >0 if OK
	 */
	function fetchTimePlanned($id, $fk_task=0)
	{
		global $langs;

		$sql = "SELECT";
		$sql.= " t.rowid,";
		$sql.= " t.fk_task,";
		$sql.= " t.task_date,";
		$sql.= " t.task_datehour,";
		$sql.= " t.task_date_withhour,";
		$sql.= " t.task_duration,";
		$sql.= " t.fk_user,";
		$sql.= " t.note";
		$sql.= " FROM ".MAIN_DB_PREFIX."projet_task_schedule as t";
		if ($id > 0 )
			$sql.= " WHERE t.rowid = ".$id;
		else
			$sql.= " WHERE t.fk_task= ".$fk_task;
		
		dol_syslog(get_class($this)."::fetchTimeSpentPlanned", LOG_DEBUG);
		$resql=$this->db->query($sql);
		if ($resql) {
			if ($this->db->num_rows($resql)) {
				$obj = $this->db->fetch_object($resql);

				$this->timeplanned_id		= $obj->rowid;
				$this->id					= $obj->fk_task;
				$this->timeplanned_date		= $this->db->jdate($obj->task_date);
				$this->timeplanned_datehour	= $this->db->jdate($obj->task_datehour);
				$this->timeplanned_withhour	= $obj->task_date_withhour;
				$this->timeplanned_duration	= $obj->task_duration;
				$this->timeplanned_fk_user	= $obj->fk_user;
				$this->timeplanned_note		= $obj->note;
			}

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

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

	/**
	 *  Load all records of time spent
	 *
	 *  @param	User	$userobj			User object
	 *  @param	string	$morewherefilter	Add more filter into where SQL request (must start with ' AND ...')
	 *  @return int							<0 if KO, array of time spent if OK
	 */
	function fetchAllTimePlanned(User $userobj, $morewherefilter='')
	{
		global $langs;

		$arrayres=array();

		$sql = "SELECT";
		$sql.= " s.rowid as socid,";
		$sql.= " s.nom as thirdparty_name,";
		$sql.= " s.email as thirdparty_email,";
		$sql.= " ptt.rowid,";
		$sql.= " ptt.fk_task,";
		$sql.= " ptt.task_date,";
		$sql.= " ptt.task_datehour,";
		$sql.= " ptt.task_date_withhour,";
		$sql.= " ptt.task_duration,";
		$sql.= " ptt.fk_user,";
		$sql.= " ptt.note,";
		$sql.= " pt.rowid as task_id,";
		$sql.= " pt.ref as task_ref,";
		$sql.= " pt.label as task_label,";
		$sql.= " p.rowid as project_id,";
		$sql.= " p.ref as project_ref,";
		$sql.= " p.title as project_label,";
		$sql.= " p.public as public";
		$sql.= " FROM ".MAIN_DB_PREFIX."projet_task_schedule as ptt, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet as p";
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid";
		$sql.= " WHERE ptt.fk_task = pt.rowid AND pt.fk_projet = p.rowid";
		$sql.= " AND ptt.fk_user = ".$userobj->id;
		$sql.= " AND pt.entity IN (".getEntity('project').")";
		if ($morewherefilter) $sql.=$morewherefilter;

		dol_syslog(get_class($this)."::fetchAllTimeSpent", LOG_DEBUG);
		$resql=$this->db->query($sql);
		if ($resql) {
			$num = $this->db->num_rows($resql);

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

				$newobj = new stdClass();

				$newobj->socid              = $obj->socid;
				$newobj->thirdparty_name    = $obj->thirdparty_name;
				$newobj->thirdparty_email   = $obj->thirdparty_email;

				$newobj->fk_project			= $obj->project_id;
				$newobj->project_ref		= $obj->project_ref;
				$newobj->project_label		= $obj->project_label;
				$newobj->public				= $obj->project_public;

				$newobj->fk_task			= $obj->task_id;
				$newobj->task_ref			= $obj->task_ref;
				$newobj->task_label			= $obj->task_label;

				$newobj->timeplanned_id			= $obj->rowid;
				$newobj->timeplanned_date		= $this->db->jdate($obj->task_date);
				$newobj->timeplanned_datehour	= $this->db->jdate($obj->task_datehour);
				$newobj->timeplanned_withhour	= $obj->task_date_withhour;
				$newobj->timeplanned_duration	= $obj->task_duration;
				$newobj->timeplanned_fk_user	= $obj->fk_user;
				$newobj->timeplanned_note		= $obj->note;

				$arrayres[] = $newobj;

				$i++;
			}

			$this->db->free($resql);
		} else {
			dol_print_error($this->db);
			$this->error="Error ".$this->db->lasterror();
			return -1;
		}

		return $arrayres;
	}

	/**
	 *	Update time spent
	 *
	 *  @param	User	$user           User id
	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
	 *  @return	int						<0 if KO, >0 if OK
	 */
	function updateTimePlanned($user, $notrigger=0)
	{
		global $conf,$langs;

		$ret = 0;

		// Clean parameters
		if (empty($this->timeplanned_datehour)) 
			$this->timeplanned_datehour = $this->timeplanned_date;
		if (isset($this->timeplanned_note)) 
			$this->timeplanned_note = trim($this->timeplanned_note);

		$this->db->begin();

		$sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_schedule SET";
		$sql.= " task_date = '".$this->db->idate($this->timeplanned_date)."',";
		$sql.= " task_datehour = '".$this->db->idate($this->timeplanned_datehour)."',";
		$sql.= " task_date_withhour = ".(empty($this->timeplanned_withhour)?0:1).",";
		$sql.= " task_duration = ".$this->timeplanned_duration.",";
		$sql.= " fk_user = ".$this->timeplanned_fk_user.",";
		$sql.= " note = ".(isset($this->timeplanned_note)?"'".$this->db->escape($this->timeplanned_note)."'":"null");
		$sql.= " WHERE rowid = ".$this->timeplanned_id;

		dol_syslog(get_class($this)."::updateTimePlanned", LOG_DEBUG);
		if ($this->db->query($sql)) {
			if (! $notrigger) {
				// Call trigger
				$result=$this->call_trigger('TASK_TIMEPLANNED_MODIFY',$user);
				if ($result < 0) {
					$this->db->rollback();
					$ret = -1;
				}
				else 
					$ret = 1;
				// End call triggers
			} else 
				$ret = 1;
		} else {
			$this->error=$this->db->lasterror();
			$this->db->rollback();
			$ret = -1;
		}

		if ($ret >= 0) $this->db->commit();
		return $ret;
	}

	/**
	 *  Delete time spent
	 *
	 *  @param	User	$user        	User that delete
	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
	 *  @return	int						<0 if KO, >0 if OK
	 */
	function delTimePlanned($user, $notrigger=0)
	{
		global $conf, $langs;

		$error=0;

		$this->db->begin();

		$sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_schedule";
		$sql.= " WHERE rowid = ".$this->timeplanned_id;

		dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG);
		$resql = $this->db->query($sql);
		if (! $resql) {
			$error++; 
			$this->errors[]="Error ".$this->db->lasterror(); 
		}

		if (! $error) {
			if (! $notrigger) {
				// Call trigger
				$result=$this->call_trigger('TASK_TIMEPLANNED_DELETE',$user);
				if ($result < 0) { $error++; }
				// End call triggers
			}
		}

		// Commit or rollback
		if ($error) {
			foreach($this->errors as $errmsg) {
				dol_syslog(get_class($this)."::delTimePlanned ".$errmsg, LOG_ERR);
				$this->error.=($this->error?', '.$errmsg:$errmsg);
			}
			$this->db->rollback();
			return -1*$error;
		} else {
			$this->db->commit();
			return 1;
		}
	}
}