<?php
	require_once( $GLOBALS["site_root"] . "/includes/models/TaskManager.inc.php" );
	require_once( $GLOBALS["site_root"] . "/includes/models/Member.inc.php" );
	require_once( $GLOBALS["site_root"] . "/includes/models/Globals.inc.php" );

	require_once( $GLOBALS["site_root"] . "/includes/urlgen/Job.inc.php" );
	require_once( $GLOBALS["site_root"] . "/includes/urlgen/TranslatorJobs.inc.php" );
	require_once( $GLOBALS["site_root"] . "/includes/urlgen/MyUser.inc.php" );
	require_once( $GLOBALS["site_root"] . "/includes/urlgen/MyMember.inc.php" );

	class JobModel {
		public function addJob( $p ) {
			$ins = array();
			$ins["job_version"]=(isset( $p["job_version"] )) ? $p["job_version"] : 3.0;
			if (isset( $p["ctstamp"] )) $ins["ctstamp"]=sprintf( "'%s'" , FNTH_db_addslashes(  $p["ctstamp"] ) );
			if (isset( $p["poster_user_id"] ))
				$ins["poster_user_id"]=sprintf( "%d" , $p["poster_user_id"] );
			$ins["poster_name"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["poster_name"] ) );
			$ins["poster_email"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["poster_email"] ) );
			$ins["poster_phone"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["poster_phone"] ) );
			if (isset( $p["poster_cellular"] )) $ins["poster_cellular"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["poster_cellular"] ) );
			$ins["poster_show_phone"]=(isset( $p["poster_show_phone"] ) && $p["poster_show_phone"]) ? "true" : "false";
			$ins["job_title"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_title"] ) );
			if (isset( $p["job_quote_deadline"] )) $ins["job_quote_deadline"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_quote_deadline"] ) );
			if (isset( $p["job_deadline"] )) $ins["job_deadline"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_deadline"] ) );
			$ins["job_description"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_description"] ) );
			if (isset( $p["job_mainaspects"] )) $ins["job_mainaspects"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_mainaspects"] ) );
			if (isset( $p["job_qualitypreference"] )) $ins["job_qualitypreference"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_qualitypreference"] ) );
			$ins["job_recipients"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_recipients"]["type"] ) );
			if (isset( $p["poster_acknowledged"] )) $ins["poster_acknowledged"] = ($p["poster_acknowledged"]) ? "true" : "false";
			if (isset( $p["admin_acknowledged"] )) $ins["admin_acknowledged"] = ($p["admin_acknowledged"]) ? "true" : "false";
			if (isset( $p["is_revoked"] )) $ins["is_revoked"]=($p["is_revoked"]) ? "true" : "false";
			if (isset( $p["revoked_at"] )) $ins["revoked_at"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["revoked_at"] ) );
			if (isset( $p["is_sent"] )) $ins["is_sent"]=($p["is_sent"]) ? "true" : "false";
			if (isset( $p["sent_at"] )) $ins["sent_at"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["sent_at"] ) );
			$ins["ipaddress"]=sprintf( "'%s'" , FNTH_db_addslashes( 
				(isset( $p["ipaddress"] )) ? $p["ipaddress"] : fo3_get_remote_ipaddress() ) );
			$ins["useragent"]=sprintf( "'%s'" , FNTH_db_addslashes(
				(isset( $p["useragent"] )) ? $p["useragent"] : $_SERVER["HTTP_USER_AGENT"] ) );
			$ins["hash"]=(isset( $p["hash"] )) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["hash"] ) ) :
				sprintf( "'%s'" , md5( uniqid("") ) );

			if (isset( $p["send_status"] )) $ins["send_status"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["send_status"] ) );
			if (isset( $p["job_specialty"])) $ins["job_specialty"]=sprintf( "%d" , $p["job_specialty"] );
			if (isset( $p["job_custom_specialty"] )) $ins["job_custom_specialty"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_custom_specialty"] ) );

			if (isset( $p["npublic_comment"] )) $ins["npublic_comment"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["npublic_comment"] ) );

			$lang_id = (isset( $p["site_language_id"] )) ? $p["site_language_id"] : $GLOBALS["languages"][ $GLOBALS["language"] ];
	
			$ins["site_language_id"]=$lang_id;

			$default_source = GlobalsModel::getSiteDomain( $GLOBALS["language"] );
			
			$default_source = 
			$ins["source"]=(isset( $p["source"] )) ? 
				sprintf( "'%s'" , FNTH_db_addslashes( $p["source"] ) ) :
				sprintf( "'%s'" , $default_source );

			if (isset( $p["oldid"] ))
				$ins["oldid"]=sprintf( "%d" , $p["oldid"] );
			
			$query = FNTH_db_generate_insert_query( "jobs" , $ins );
			FNTH_db_free_result( FNTH_db_query( $query ) );
			$job_id = FNTH_db_get_field( "select currval( 'jobs_job_id_seq') as num" , "num" );

			// custom recipients
			if ($p["job_recipients"]["type"]=="custom" && isset( $p["job_recipients"]["custom_recipients"] ))
				$this->setJobCustomRecipients( $job_id , $p["job_recipients"]["custom_recipients"] );
			// add languages
			if (isset( $p["job_languages"] ))
				$this->setJobLanguages( $job_id , $p["job_languages"] );
			// add services
			if (isset( $p["job_services"] ))
				$this->setJobServices( $job_id , $p["job_services"] );
			return $job_id;
		}

		public function updateJob( $job_id , $p = array() ) {
			$upd = array();
			if (isset( $p["job_version"] )) $upd["job_version"]=sprintf( "%f" , $p["job_version"] );

			if (isset( $p["job_title"] )) $upd["job_title"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_title"] ));
			if (isset( $p["job_description"] )) $upd["job_description"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_description"] ));
			// timestamps
			if (isset( $p["ctstamp"] )) $upd["ctstamp"]=(strlen(trim($p["ctstamp"]))) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["ctstamp"] )) : "null";
			if (isset( $p["job_quote_deadline"] )) $upd["job_quote_deadline"]=(strlen(trim($p["job_quote_deadline"]))) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["job_quote_deadline"] )) : "null";
			if (isset( $p["job_deadline"] )) $upd["job_deadline"]=(strlen(trim($p["job_deadline"]))) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["job_deadline"] )) : "null";
			if (isset( $p["closed_at"] )) $upd["closed_at"]=(strlen(trim($p["closed_at"]))) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["closed_at"] )) : "null";
			if (isset( $p["revoked_at"] )) $upd["revoked_at"]=(strlen(trim($p["revoked_at"]))) ? sprintf( "'%s'" , FNTH_db_addslashes( $p["revoked_at"] )) : "null";

			// booleans
			if (isset( $p["is_closed"] )) $upd["is_closed"]=($p["is_closed"]) ? "true" : "false";
			if (isset( $p["is_revoked"] )) $upd["is_revoked"]=($p["is_revoked"]) ? "true" : "false";
			if (isset( $p["poster_acknowledged"] )) $upd["poster_acknowledged"]=($p["poster_acknowledged"]) ? "true" : "false";
			if (isset( $p["admin_acknowledged"] )) $upd["admin_acknowledged"]=($p["admin_acknowledged"]) ? "true" : "false";
			if (isset( $p["is_proofread"] )) $upd["is_proofread"]=($p["is_proofread"]) ? "true" : "false";


			if (isset( $p["job_recipients"] )) {
				$upd["job_recipients"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["job_recipients"]["type"] ) );
				if ($p["job_recipients"]["type"]=="custom" && isset( $p["job_recipients"]["custom_recipients"] )) {
					$this->setJobCustomRecipients( $job_id , $p["job_recipients"]["custom_recipients"] );
				}
			}
			
			if (isset( $p["npublic_comment"] )) $upd["npublic_comment"]=sprintf( "'%s'" , FNTH_db_addslashes( $p["npublic_comment"] ) );

			$q = FNTH_db_generate_update_query( "jobs" , $upd , sprintf( "job_id=%d" , $job_id ) );
			FNTH_db_free_result( FNTH_db_query( $q ) );
			return $job_id;
		}

		public function deleteJob( $job_id ) {
			$this->setJobLanguages( $job_id , array() );
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_servicetypes where job_id=%d" , $job_id )));
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_notifications where job_id=%d" , $job_id )));
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_quotes where job_id=%d" , $job_id )));
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_custom_recipients where job_id=%d" , $job_id )));
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from jobs where job_id=%d", $job_id )));

		}

		public function setJobLanguages( $job_id , $p = array() ) {
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_langpairs where job_id=%d" , $job_id ) ) );
			$i=1;
			foreach ($p as $row) {
				$ins = array();
				$ins["job_id"]=sprintf( "%d" , $job_id );
				$ins["ordering"]=$i;
				$ins["source_language_id"]=sprintf( "%d" , $row["source_language_id"] );
				$ins["target_language_id"]=sprintf( "%d" , $row["target_language_id"] );
				FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_insert_query( "job_langpairs" , $ins ) ) );
				$i++;
			}
		}

		public function clearJobSent( $job_id ) {
			$upd = array();
			$upd["is_sent"]="false";
			$upd["sent_at"]="null";
			$upd["activate_task_id"]="null";
			$upd["send_task_id"]="null";
			FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_update_query( "jobs" , $upd , sprintf( "job_id=%d", $job_id ) ) ) );
		}

		public function setJobServices( $job_id , $p = array() ) {
			FNTH_db_free_result( FNTH_db_query( sprintf( "delete from job_servicetypes where job_id=%d" , $job_id ) ) );
			$i=1;
			foreach ($p as $servicetype_id => $service) {
				$ins = array();
				$ins["job_id"]=sprintf( "%d" , $job_id );
				$ins["servicetype_id"]=sprintf( "%d" , $servicetype_id );
				$ins["servicetype_unit_id"]=sprintf( "%d" , $service["unit"] );
				$ins["quantity"]=sprintf( "%d" , $service["quantity"] );
				if (isset( $service["loc"] ))
					$ins["location"]=sprintf( "'%s'" , FNTH_db_addslashes( $service["loc"] ) );

				FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_insert_query( "job_servicetypes" , $ins ) ) );
			}
		}

		public function setJobCustomRecipients( $job_id , $member_ids ) {
			FNTH_db_free_result(
				FNTH_db_query( sprintf( "delete from job_custom_recipients where job_id=%d" , $job_id ) ) );
			if (!count( $member_ids )) return;
			foreach ($member_ids as $member_id) {
				$ins = array();
				$ins["job_id"]=$job_id;
				$ins["member_id"]=sprintf( "%d" , $member_id );
				FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_insert_query( "job_custom_recipients" , $ins ) ) );
			}
		}

		public function getJobLanguages( $job_id ) {
			$query = sprintf( "select * from job_langpairs where job_id=%d order by ordering" , $job_id );
			$retval = FNTH_db_get_resultset( $query );
			return $retval;
		}

		public function getJobServices( $job_id ) {
			$query = sprintf( "select * from job_servicetypes where job_id=%d" , $job_id );
			$ds = FNTH_db_get_resultset( $query );
			$retval = array();
			foreach ($ds as $row) {
				$item = array(
					"unit" => $row["servicetype_unit_id"],
					"quantity" => $row["quantity"] );
				if (isset( $row["location"] )) $item["loc"]=$row["location"];
				$retval[$row["servicetype_id"]] = $item;
			}
			return $retval;
		}

		public function getJobCustomRecipients( $job_id ) {
			return FNTH_db_get_column( sprintf( "select member_id from job_custom_recipients where job_id=%d",$job_id ) , "member_id" );
		}

		protected function prepareJob( $row , $lang = "hu" ) {
			$retval = $row;
			$job_id = $row["job_id"];

			// formazott datumok
			$retval["job_quote_deadline_datetime"]=fo3_format_datetime_to_screen( $row["job_quote_deadline"] );
			$retval["job_deadline_datetime"]=fo3_format_datetime_to_screen( $row["job_deadline"] );

			// attachments
			$retval["job_attachments"]=$this->getJobAttachments( $job_id );
			// languages
			$retval["job_languages"]=$this->getJobLanguages( $job_id );
			// services
			$retval["job_services"]=$this->getJobServices( $job_id );
			// recipients
			$retval["job_recipients"] = array(
				"type" => $row["job_recipients"] );
			if ($retval["job_recipients"]["type"]=="custom")
				$retval["job_recipients"]["custom_recipients"]=$this->getJobCustomRecipients( $job_id );

			// job url
			$u = array( "job_id" => $job_id );
			$retval["job_url"]=TranslatorJobsURL::renderURL( $u , $lang );
			// quotes of job url
			$retval["quotes_of_job_url"]=JobURL::renderQuotesOfJobURL( $job_id , array() , $lang );

			// number of quotes
			$retval["number_of_quotes"]=$this->getNumberOfJobQuotes( $job_id , "all" );
			$retval["number_of_quotes_accepted"]=$this->getNumberOfJobQuotes( $job_id , "accepted" );
			$retval["number_of_quotes_declined"]=$this->getNumberOfJobQuotes( $job_id , "declined" );
			$retval["number_of_quotes_undecided"]=$this->getNumberOfJobQuotes( $job_id , "undecided" );

			$muu = new MyUserURL();
			$retval["close_job_url"]=$muu->renderQuoteRequestCloseURL( array( "hash" => $row["hash"] ) );
			$retval["revoke_job_url"]=$muu->renderQuoteRequestRevokeURL( array( "hash" => $row["hash"] ) );
			
			return $retval;
		}
		
		protected function getNumberOfJobQuotes( $job_id , $type = "all" ) {
			$query = sprintf( "select count(*) as num from job_quotes where job_id=%d" , $job_id );
			switch ($type) {
			default:
			case "all":break;
			case "accepted":$query.=" and is_accepted";break;
			case "declined":$query.=" and not is_accepted";break;
			case "undecided":$query.=" and is_accepted is null";break;
			}
			return FNTH_db_get_field( $query , "num" );
		}

		public function getJobFromId( $job_id , $full = false , $lang = "hu" ) {
			$query = sprintf( "select * from jobs where job_id=%d" , $job_id );
			$row = FNTH_db_get_row( $query );
			if (!$row) return $row;
			if (!$full) return $row;
			$retval = $this->prepareJob( $row , $lang );
			return $retval;
		}

		public function prepareAttachment( $ja ) {
			$ja["icon"]=fo3_get_mimetype_icon_path( $ja["attachment_mimetype"] );
			$ja["attachment_url"]=JobURL::renderJobAttachmentURL( $ja["job_attachment_id"] );
			return $ja;
		}

		public function getJobAttachments( $job_id ) {
			$query = sprintf( "select * from job_attachments where job_id=%d" , $job_id );
			$ds = FNTH_db_get_resultset( $query );
			if (empty( $ds )) return $ds;
			$retval = array();
			foreach ($ds as $row) $retval[]=$this->prepareAttachment( $row );
			return $retval;
		}

		public function getJobAttachment( $job_attachment_id ) {
			$query = sprintf( "select * from job_attachments where job_attachment_id=%d" , $job_attachment_id );
			$retval = FNTH_db_get_row( $query );
			if (!$retval) return $retval;
			return $this->prepareAttachment( $retval );
		}

		public function getJobFromHash( $hash , $full = false ) {
			$query = sprintf( "select job_id from jobs where hash='%s'" , FNTH_db_addslashes( $hash ) );
			$job_id = FNTH_db_get_field( $query , "job_id" );
			if (!$job_id) return false;
			return $this->getJobFromId( $job_id ,$full );
		}

		public function acknowledgeJob( $job_id , $val = true ) {
			$v = ($val) ? "true" : "false";
			$query = sprintf( "update jobs set poster_acknowledged=%s where job_id=%d" , $v , $job_id );
			FNTH_db_free_result( FNTH_db_query( $query ) );
		}
		
		public function adminAcknowledgeJob( $job_id , $val = true ) {
			$v = ($val) ? "true" : "false";
			$query = sprintf( "update jobs set admin_acknowledged=%s where job_id=%d" , $v , $job_id );
			FNTH_db_free_result( FNTH_db_query( $query ) );
		}

		public function activateJob( $job_id ) {
			$tm = new TaskManagerModel();
			$tm->newTask();
			$tm->setTaskName( sprintf( "activating job #%d" , $job_id ) );
	
			$job = $this->getJobFromId( $job_id );
			$tm->setTaskDescription( $job["job_title"] );
			$tm->setTaskType( "job_activation" );
			$tm->setTaskUID( $job_id );
			$task_id = $tm->saveNewTask();
			FNTH_db_free_result(
				FNTH_db_query(
					sprintf( "update jobs set activate_task_id=%d where job_id=%d" , $task_id , $job_id ) ) );
		}

		protected function getAttachmentPath( $job_id ) {
			return sprintf( "/media/job-attachments/%d/%03d/%03d",
				(int)($job_id/1000000),
				((int)($job_id/1000))%1000,
				$job_id%1000 );
		}

		public function addJobAttachment( $job_id , $attachment = array() ) {
			if (!isset( $attachment["real_path"] )) return false;
			if (!file_exists( $attachment["real_path"] )) return false;
			$fsize = filesize( $attachment["real_path"] );
			if (!$fsize) return false;

			$ins = array();
			$ins["job_id"]=$job_id;
			$ins["attachment_title"] = sprintf( "'%s'" , FNTH_db_addslashes( $attachment["comment"] ) );
			$ins["attachment_type"]="'general'";
			$ins["attachment_mimetype"]=sprintf( "'%s'" , FNTH_db_addslashes( $attachment["mime_type"] ) );
			$ins["attachment_original_filename"]=sprintf( "'%s'", FNTH_db_addslashes( $attachment["filename"] ) );
			$ins["attachment_path"]=sprintf( "'%s'" , FNTH_db_addslashes( $this->getAttachmentPath( $job_id ) ) );
			$filename = uniqid("");
			$ins["attachment_filename"]=sprintf( "'%s'" , FNTH_db_addslashes( $filename ) );
			$ins["attachment_filesize"]=sprintf( "%d" , $fsize );
			$q = FNTH_db_generate_insert_query( "job_attachments" , $ins );
			FNTH_db_free_result( FNTH_db_query( $q ) );

			$fullpath = $GLOBALS["site_root"] . $this->getAttachmentPath( $job_id );
			if (!is_dir( $fullpath )) mkdir( $fullpath , 0777 , true );
			copy( $attachment["real_path"] , $fullpath . "/" . $filename );
			return true;
		}

		public function getLastJobsFromPoster( $user_id , $limit = 1 ) {
			$query = sprintf( "select * from jobs where poster_user_id = %d order by job_id desc limit %d",
				$user_id , $limit );
			return FNTH_db_get_resultset( $query );
		}


		public function sendJob( $job_id ) {
			$tm = new TaskManagerModel();
			$tm->newTask();
			$tm->setTaskName( sprintf( "sending job notifications #%d" , $job_id ) );
	
			$job = $this->getJobFromId( $job_id );
			$tm->setTaskDescription( $job["job_title"] );
			$tm->setTaskType( "job_notification" );
			$tm->setTaskUID( $job_id );
			$task_id = $tm->saveNewTask();
			FNTH_db_free_result(
				FNTH_db_query(
					sprintf( "update jobs set send_task_id=%d where job_id=%d" , $task_id , $job_id ) ) );
		}

		/* RIGHTS */

		public function isJobOwnedByUser( $job_id , $user_id , $job = false ) {
			if (!$job_id) return false;								// ervenytelen job
			if (!$user_id) return false;							// ervenytelen user
			if (!$job) $job = $this->getJobFromId( $job_id );
			if (isset( $job["poster_user_id"] ) && $job["poster_user_id"]==$user_id) return true;
			return false;
		}

		public function isJobMemberType( $job_id = 0 , $member_id = 0 , $full_job = false , $member = false ) {
			if (!$job_id) return false;								// ervenytelen job
			if (!$member_id) return false;							// ervenytelen member
			if (!$full_job) $full_job = $this->getJobFromId( $job_id , true );
			// caching
			$mm = new MemberModel();
			if (!$member) {
				$member = $mm->getMemberFromMemberId( $member_id );
			}
			if (!$member) return false;								// tovabbra sem tudtuk beolvasni
			switch ($full_job["job_recipients"]["type"]) {
			default:
			case "freelancers":										// ezt is mindenki csak esszel
			case "all":
				switch ($member["member_type"]) {
				case "parttime":
					// reszidosnek csak akkor szol, hogy ha az o nyelvei benne vannak
					$member_langs = $mm->getMemberLanguages( $member["member_id"] );
					foreach ($full_job["job_languages"] as $langs) {
						if (in_array( $langs["source_language_id"] , $member_langs ) &&
							in_array( $langs["target_language_id"] , $member_langs )) return true;
					}
					return false;
				default:
					return true;								// ez meg alapbol mindenki
				}
			case "agencies":										// forditoiroda az custom
				if ($member["member_type"]=="agency") return true;
				return false;
			case "custom":
				return in_array( $member_id , $full_job["job_recipients"]["custom_recipients"] );
			}
		}

		public function isJobQuotedByMember( $job_id , $member_id , $full_job = false , $member = false ) {
			$query = sprintf( "select count(*) as num from job_quotes where job_id=%d and member_id=%d",
				$job_id,$member_id );
			$num = FNTH_db_get_field( $query , "num" );
			return ($num>0);
		}
		
		public function isJobQuotedByMemberAccepted( $job_id , $member_id , $full_job = false , $member = false ) {
			$query = sprintf( "select count(*) as num from job_quotes where job_id=%d and member_id=%d and is_accepted",
				$job_id,$member_id );
			$num = FNTH_db_get_field( $query , "num" );
			return ($num>0);
		}

		public function isJobContactAvailableForUser( $job_id  , $user_id , $full_job = false ) {
			if (!$job_id) return false;								// ervenytelen job
			if (!$user_id) return false;							// ervenytelen user
			if (!$full_job) $full_job = $this->getJobFromId( $job_id , true );
			if (!$full_job) return false;
			// ha nem lathatja, akkor akkor egyertelmu nem
			if (!$this->isJobAvailableForUser( $job_id , $user_id , $full_job )) return false;
			// meg nem jart le, vagyis lathatja
			if ($full_job["job_quote_deadline"]>fo3_date( "Y-m-d H:i:s" )) return true;
			// regi melo, mert nincs munka hatarideje
			if (!isset( $full_job["job_deadline"] )) return false;
			$mm = new MemberModel();
			$member = $mm->getMemberFromUserId( $user_id );
			if (!$member) return false;

			$is_job_quoted = $this->isJobQuotedByMember( $job_id , $member["member_id"] , $full_job , $member );
			if ($full_job["job_deadline"]>fo3_date( "Y-m-d H:i:s" ) && $is_job_quoted) return true;
			$is_job_quote_accepted = $this->isJobQuotedByMemberAccepted( $job_id , $member["member_id"] , $full_job , $member );
			if ($is_job_quote_accepted) return true;
			return false;
		}

		public function isJobAvailableForUser( $job_id , $user_id , $full_job = false ) {
			if (!$job_id) return false;								// ervenytelen job
			if (!$user_id) return false;							// ervenytelen user
			if (!$full_job) $full_job = $this->getJobFromId( $job_id , true );
			if ($this->isJobOwnedByUser( $job_id , $user_id , $full_job)) return true;	// elerheto hiszen az ove
			$mm = new MemberModel();
			$member = $mm->getMemberFromUserId( $user_id );
			if (!$member) return false;								// nincs member, nincs suti

			// SL110531 - kinyitjuk, ha o az egyetlen arc, akinek szol
			if ($full_job["job_recipients"]["type"]=="custom") {
				$mmm = new MyMemberModel();
				$member_id = $mmm->getLoggedInMemberId();
				$member_ids = $full_job["job_recipients"]["custom_recipients"];
				if (in_array( $member_id , $member_ids ) && count( $member_ids )==1)
					return true;
			}

			if (!$mm->isMemberActiveSubscriber( $member["member_id"] , $member )) return false; // nem aktiv

			return $this->isJobMemberType( $job_id , $member["member_id"] , $full_job , $member );
		}


		public function isJobQuoteAvailableForUser( $job_id , $user_id ) {
			if (!$job_id) return false;								// ervenytelen job
			if (!$user_id) return false;							// ervenytelen user
			$mm = new MemberModel();
			$member = $mm->getMemberFromUserId( $user_id );	// get member
			if (!$member) return false;								// nem member
			// ha sajat maga birtokaban van
			if ($this->isJobOwnedByUser( $job_id , $user_id )) return false;


			// SL110531 - kinyitjuk, ha o az egyetlen arc, akinek szol
			$full_job = $this->getJobFromId( $job_id , true );
			if ($full_job["job_recipients"]["type"]=="custom") {
				$mmm = new MyMemberModel();
				$member_id = $mmm->getLoggedInMemberId();
				$member_ids = $full_job["job_recipients"]["custom_recipients"];
				if (in_array( $member_id , $member_ids ) && count( $member_ids )==1)
					return true;
			}
			
			// ha lejart a csoka
			$member_id = $member["member_id"];
			if (!$mm->isMemberActiveSubscriber( $member_id , $member )) return false;
			return $this->isJobAvailableForUser( $job_id , $user_id );
		}

		/* RECIPIENTS */
		public function isMemberJobRecipient( $member , $job ) {
			// -- magarol ne kapjon
			if ($member["user_id"]==$job["poster_user_id"]) return false; 
			// torolt member
			if ($member["is_deleted"]=="t") return false;
			switch ($member["current_status"]) {
			case STATUS_DELETED:
			case STATUS_NEW_USER_DELETED:
				return false;
			}

			// -- esetleges expiration (bar nem kene): ha lejart, nem kap
			// -- bar kene kapnia, mert teasing
			// if ($member["expires_tstamp"]<fo3_date( "Y-m-d H:i:s")) return false;

			// -- ha a job agencynek szol, akkor kizarolag az agencyk kaphatjak
			if ($job["job_recipients"]["type"]=="agencies") {
				if ($member["member_type"]!="agency") return false;
			} else	if ($job["job_recipients"]["type"]=="custom") {
				// ha custom, akkor csak a customok
				return in_array( $member["member_id"] , $job["job_recipients"]["custom_recipients"] );
			}

			// -- ha mindenrol ker ertesitot, akkor ezek szerint ez is az ove
			if ($member["notifications"]=="all") return true;

			$mm = new MemberModel();
			switch ($member["notifications"]) {
			case "no":	// mar egyszer volt egy ilyen, de biztos ami tuti
				return false;
			case "mylangs":
				$member_langs = $mm->getMemberLanguages( $member["member_id"] );
				// -- sajat nyelves, csak a sajat bejelolt nyelveibol akar

				// barmelyik, kiveve a magyar
				if (!isset( $job["job_languages"] )) return false;		// ez itt ellenorzes hianya
				foreach ($job["job_languages"] as $jl) {
					$langs = array();
					$langs[]=$jl["source_language_id"];
					$langs[]=$jl["target_language_id"];
					foreach ($langs as $lang_id) {
						if ($lang_id==1) continue;	// magyar dirty hack
						if (in_array( $lang_id , $member_langs )) return true;
					}
				}
				return false;
			case "mypairs":
				// -- minden nyelvparjanak stimmelnie kell
				// -- vagyis minden, a munkaajanlatban megadott nyelvparnak kell szerepelnie
				// -- minden megadott szolgaltatason

				$mlp = $mm->getMemberLanguagePairs3D( $member["member_id"] );
				$s = array_keys( $job["job_services"] );
				foreach ($job["job_languages"] as $jl) {
					foreach ($s as $stid)
						if (!isset( $mlp[$stid][ $jl["source_language_id"] ][ $jl["target_language_id"] ] ))
							return false;
				}
				break;
			}
			return true;
		}

		public function abandonOldJob( $oldid ) {
			$ins = array();
			$ins["oldid"]=sprintf( "%d" , $oldid );
			$q = FNTH_db_generate_insert_query( "jobs_abandoned" , $ins );
			FNTH_db_free_result( FNTH_db_query( $q ) );
		}

		public function isOldJobAbandoned( $oldid ) {
			$query = sprintf( "select count(*) as num from jobs_abandoned where oldid=%d" , $oldid );
			$retval = FNTH_db_get_field( $query , "num" );
			return ($retval>0);
		}

		public function revokeJob( $job_id ) {
			$upd = array();
			$upd["is_revoked"]="true";
			$upd["revoked_at"]="now()";
			$q = FNTH_db_generate_update_query( "jobs" , $upd , sprintf( "job_id=%d" , $job_id ) );
			FNTH_db_free_result( FNTH_db_query( $q ) );
		}
		
		public function closeJob( $job_id ) {
			$upd = array();
			$upd["is_closed"]="true";
			$upd["closed_at"]="now()";
			$q = FNTH_db_generate_update_query( "jobs" , $upd , sprintf( "job_id=%d" , $job_id ) );
			FNTH_db_free_result( FNTH_db_query( $q ) );
		}


		public function generateJobRecipients( $job_id ) {
			$job = $this->getJobFromId( $job_id , true );
			// -- eloszor a custom, akkor tuti biztos, hogy kifiaborja
			if ($job["job_recipients"]["type"]=="custom") return $this->getJobCustomRecipients( $job_id );

			// -- aztan kicsit elokeszitjuk a nyelveket
			$job_langs = array();
			foreach ($job["job_languages"] as $jlp) {
				$job_langs[ $jlp["source_language_id"] ] = true;
				$job_langs[ $jlp["target_language_id"] ] = true;
			}
			$job["job_langs"]=array_keys( $job_langs );


			// -- akkor eloszor is mindenki aki kert
			$query = sprintf( "select * from members where notifications<>'no'" );
			$res = FNTH_db_query( $query );
			$retval = array();
			while ($member = FNTH_db_fetch( $res )) {
				if (!$this->isMemberJobRecipient( $member , $job )) continue;
				$retval[]=$member["member_id"];
			}
			FNTH_db_free_result( $res );
			return $retval;
		}

		public function getJobFilter( $filter_name , $p = array() ) {
			$retval = "";
			switch ($filter_name) {
			case "currents":
				$retval = sprintf( "(jobs.job_quote_deadline>='%s' and poster_acknowledged and admin_acknowledged)" , fo3_date( "Y-m-d H:i:s" ) );
				break;
			case "not_expireds":
				$retval = sprintf( "jobs.job_quote_deadline>='%s'" , fo3_date( "Y-m-d H:i:s" ) );
				break;
			case "expireds":
				$retval = sprintf( "(jobs.job_quote_deadline<'%s' and poster_acknowledged and admin_acknowledged and jobs.job_version=3)" , fo3_date( "Y-m-d H:i:s" ) );
				break;
			case "posted_by_me":
				$retval = sprintf( "jobs.poster_user_id=%d" , $p["user_id"] );
				break;
			case "status_open":
				$retval = sprintf( "(not jobs.is_revoked and not jobs.is_closed and jobs.job_quote_deadline>now())");
				break;
			case "status_revoked":
				$retval = sprintf( "(jobs.is_revoked)" );
				break;
			case "status_closed":
				$retval = sprintf( "(jobs.is_closed)" );
				break;
			case "status_expired":
				$retval = sprintf( "(not jobs.is_revoked and not jobs.is_closed and jobs.job_quote_deadline<now())");
				break;
			}
			return $retval;
		}

		public function updateJobPosterUserData( $user_id ) {
			$um = new UserModel();
			$user = $um->getUserFromUserId( $user_id );
			if (!$user) return;
			$upd = array();
			$upd["poster_name"]=sprintf( "'%s'" , FNTH_db_addslashes( $user["user_name"] ) );
			$upd["poster_email"]=sprintf( "'%s'" , FNTH_db_addslashes( $user["email"] ) );
			$upd["poster_phone"]=sprintf( "'%s'" , FNTH_db_addslashes( $user["contact_phone"] ) );
			FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_update_query( "jobs" , $upd , sprintf( "poster_user_id=%d" , $user_id ) ) ) );
		}

		public function getJobStatusString( $job ) {
			if ($job["is_revoked"]=="t") {
				// revoked
				$status = __("myquoterequestspage_status_revoked" );
			} else if ($job["is_closed"]=="t") {
				// closed
				$status = __("myquoterequestspage_status_closed" );
			} else if ($job["job_quote_deadline"]<fo3_date("Y-m-d H:i:s")) {
				// expired
				$status = __("myquoterequestspage_status_after_quote_deadline");
			} else {
				// open
				$status = __("myquoterequestspage_status_open" );
			}
			return $status;
		}
	}

?>
