<?php
	/**
	* phpGroupWare - property: a Facilities Management System.
	*
	* @author Sigurd Nes <sigurdne@online.no>
	* @copyright Copyright (C) 2003,2004,2005,2006,2007 Free Software Foundation, Inc. http://www.fsf.org/
	* This file is part of phpGroupWare.
	*
	* phpGroupWare 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 2 of the License, or
	* (at your option) any later version.
	*
	* phpGroupWare 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 phpGroupWare; if not, write to the Free Software
	* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
	*
	* @license http://www.gnu.org/licenses/gpl.html GNU General Public License
	* @internal Development of this application was funded by http://www.bergen.kommune.no/bbb_/ekstern/
	* @package property
	* @subpackage export
 	* @version $Id: Agresso_X114 11532 2013-12-15 15:17:13Z sigurdne $
	*/

	/**
	 * Description
	 * @package property
	 */

	phpgw::import_class('phpgwapi.datetime');

	class export_conv
	{
		//var $fil_katalog='c:/temp'; //On windows use "//computername/share/filename" or "\\\\computername\share\filename" to check files on network shares.

		var $debug;
		var $client_code = 14;
		protected $connection = false;
		protected $global_lock = false;
		protected $orders_affected = array();
		protected $min_period;

		function  __construct()
		{
			$GLOBALS['phpgw_info']['flags']['currentapp']	=	'property';
			$this->currentapp			= $GLOBALS['phpgw_info']['flags']['currentapp'];
			$this->db 					= & $GLOBALS['phpgw']->db;
			$this->join					= & $this->db->join;

			$this->soXport 				= CreateObject('property.soXport');
			$this->config				= CreateObject('admin.soconfig',$GLOBALS['phpgw']->locations->get_id('property', '.invoice'));
			$this->cats					= CreateObject('phpgwapi.categories', -1, 'property', '.project');
			$this->cats->supress_info	= true;

			if(!isset($this->config->config_data['common']['method']))
			{
				$GLOBALS['phpgw']->redirect_link('/index.php', array('menuaction' => 'admin.uiconfig2.index', 'location_id' => $GLOBALS['phpgw']->locations->get_id('property', '.invoice')) );
			}

			if (isset($this->config->config_data['export']['cleanup_old']) && $this->config->config_data['export']['cleanup_old'])
			{
				$this->cleanup_old();
			}

			$sogeneric		= CreateObject('property.sogeneric','period_transition');
			$period_config			= $sogeneric->read(array('allrows' => true));
			
			$period_transition = array();
			foreach($period_config as $entry)
			{
				$period_transition[$entry['month']] = $entry;
			}

			$current_month = date('n');
			
			if(isset($period_transition[$current_month]))
			{
				$_lag_day = (int)$period_transition[$current_month]['day'];
				$_lag_hour = (int)$period_transition[$current_month]['hour'];
				$_lag_seconds = ($_lag_day * 24 * 3600) + ($_lag_hour * 3600);
			}
			else if(isset($period_transition[13]))
			{
				$_lag_day = (int)$period_transition[13]['day'];
				$_lag_hour = (int)$period_transition[13]['hour'];
				$_lag_seconds = ($_lag_day * 24 * 3600) + ($_lag_hour * 3600);
			}
			else
			{
				$_lag			= date('n') == 1 ? 11 : 7;//6 days into next month, 10 days into next year
				$_lag_seconds	= $_lag * 24 * 3600;
			}
			
			$_lag_seconds -= phpgwapi_datetime::user_timezone();
			
//_debug_array($period_transition);			
			$time = time();
			$timestamp_at_start_month =  mktime( $hour = 0, $minute = 0, $second = 0, $month = date("n"), $day = 0, $year = date("Y") );

			if(($time - $timestamp_at_start_month) < $_lag_seconds)
			{
				$time = $time - $_lag_seconds;			
			}

			$month = date('n', $time);
			$year = date('Y',$time);
			
			$this->min_period = sprintf("%s%02d",$year,$month);

		}

		protected function cleanup_old()
		{
			$this->db->transaction_begin();
			$date = date($this->db->datetime_format(),time());
			$sql= "UPDATE fm_ecobilag SET saksigndato = '{$date}', saksbehandlerid = 'admin' WHERE external_ref IS NULL AND saksigndato IS NULL";
//_debug_array($sql);
			$this->db->query($sql,__LINE__,__FILE__);
			$sql= "UPDATE fm_ecobilag SET budsjettsigndato = '{$date}', budsjettansvarligid = 'admin' WHERE external_ref IS NULL AND budsjettsigndato IS NULL";
//_debug_array($sql);
			$this->db->query($sql,__LINE__,__FILE__);
			$sql= "UPDATE fm_ecobilag SET utbetalingsigndato = '{$date}', utbetalingid = 'admin' WHERE external_ref IS NULL AND utbetalingsigndato IS NULL";
//_debug_array($sql);
			$this->db->query($sql,__LINE__,__FILE__);
			$this->overfor('on');

			$sql= "SELECT min(bilagsnr) as bilagsnr FROM fm_ecobilagoverf";
			$this->db->query($sql,__LINE__,__FILE__);
			$this->db->next_record();
			$bilagsnr = (int)$this->db->f('bilagsnr');
			if($bilagsnr)
			{
				$correction = $bilagsnr -1;
				$sql= "UPDATE fm_ecobilagoverf SET bilagsnr = bilagsnr - {$correction}";
//_debug_array($sql);
				$this->db->query($sql,__LINE__,__FILE__);
			}
			$this->db->transaction_commit();
		}

		protected function select_vouchers_to_transfer()
		{
			if(isset($this->config->config_data['common']['invoice_approval']) && $this->config->config_data['common']['invoice_approval']== 1)
			{
				$sql= "SELECT DISTINCT fm_ecobilag.bilagsnr FROM fm_ecobilag {$this->join} fm_ecobilag_sum_view ON fm_ecobilag.bilagsnr = fm_ecobilag_sum_view.bilagsnr WHERE approved_amount = '0.00' OR budsjettsigndato IS NOT NULL ORDER BY bilagsnr ASC";
			}
			else
			{
				$sql= "SELECT DISTINCT fm_ecobilag.bilagsnr FROM fm_ecobilag {$this->join} fm_ecobilag_sum_view ON fm_ecobilag.bilagsnr = fm_ecobilag_sum_view.bilagsnr WHERE  approved_amount = '0.00' OR ( budsjettsigndato IS NOT NULL AND (saksigndato IS NOT NULL OR oppsynsigndato IS NOT NULL) ) ORDER BY bilagsnr ASC";
			}
			$this->db->query($sql,__LINE__,__FILE__);
			$vouchers_step1 = array();
			while ($this->db->next_record())
			{
				$vouchers_step1[]	= $this->db->f('bilagsnr');
			}

			//Filter out partially approved
			$vouchers = array();
			foreach($vouchers_step1 as $bilagsnr)
			{
				$sql = "SELECT bilagsnr FROM fm_ecobilag WHERE bilagsnr = {$bilagsnr} AND budsjettsigndato IS NULL";
				$this->db->query($sql,__LINE__,__FILE__);
				if( !$this->db->next_record() )
				{
					$vouchers[] = $bilagsnr;
				}
			}


			//Add vouchers with split-line and approved amount = 0.00
			$extra_candidates = array();
			$sql = "SELECT DISTINCT bilagsnr FROM fm_ecobilag WHERE (godkjentbelop = '0' OR godkjentbelop = '0.00') AND budsjettsigndato IS NULL";
			$this->db->query($sql,__LINE__,__FILE__);
			while( $this->db->next_record() )
			{
				$extra_candidates[]	= $this->db->f('bilagsnr');
			}

			foreach($extra_candidates as $extra_candidate)
			{
				if(in_array($extra_candidate, $vouchers))
				{
					continue;
				}

				$sql = "SELECT bilagsnr,oppsynsigndato,saksigndato,budsjettsigndato FROM fm_ecobilag WHERE bilagsnr = {$extra_candidate} AND (godkjentbelop > 0 OR godkjentbelop < 0)";

				$this->db->query($sql,__LINE__,__FILE__);
				$transfer_extra 	= true;
				while( $this->db->next_record() )
				{
					$oppsynsigndato 	= $this->db->f('oppsynsigndato');
					$saksigndato		= $this->db->f('saksigndato');
					$budsjettsigndato	= $this->db->f('budsjettsigndato');

					if(isset($this->config->config_data['common']['invoice_approval']) && $this->config->config_data['common']['invoice_approval']== 1)
					{
						if(!$budsjettsigndato)
						{
							$transfer_extra = false;
						}
					}
					else
					{
						if (!$budsjettsigndato)
						{
							$transfer_extra = false;
						}
						else if ($budsjettsigndato && !$saksigndato && !$oppsynsigndato)
						{
							$transfer_extra = false;
						}
					}
				}

				if($transfer_extra)
				{
					$vouchers[] = $extra_candidate;
				}
			}

			return $vouchers;
		}

		protected function log_end($batchid)
		{
			$tid=date($this->soXport->datetimeformat);
			$sql= "insert into fm_ecologg (batchid,melding,tid) values ('$batchid','End transfer','$tid')";
			$this->db->query($sql,__LINE__,__FILE__);
		}

		protected function log_error($batchid,$error_desr)
		{
			$tid = date($this->soXport->datetimeformat);
			$sql = "INSERT INTO fm_ecologg (batchid,ecobilagid,status,melding,tid) VALUES ('$batchid',NULL,0,'$error_desr','$tid')";
			$this->db->query($sql,__LINE__,__FILE__);
		}

		protected function increment_batchid()
		{
			$this->db->query("UPDATE fm_idgenerator SET value = value + 1 WHERE name = 'Ecobatchid'",__LINE__,__FILE__);
			$this->db->query("SELECT value from fm_idgenerator WHERE name = 'Ecobatchid'",__LINE__,__FILE__);
			$this->db->next_record();
			$batchid = $this->db->f('value');
			return $batchid;
		}

		protected function next_batchid()
		{
			$this->db->query("SELECT value from fm_idgenerator WHERE name = 'Ecobatchid'",__LINE__,__FILE__);
			$this->db->next_record();
			$batchid = $this->db->f('value')+1;
			return $batchid;
		}

		//Lagre start melding
		protected function log_start($batchid)
		{
			$tid = date($this->db->datetime_format());
			$sql= "INSERT INTO fm_ecologg (batchid,melding,tid) VALUES ('$batchid','Start transfer','$tid')";
			$this->db->query($sql,__LINE__,__FILE__);
		}

		protected function get_vendor_info($vendor_id='')
		{
			$sql = "SELECT org_nr, konto_nr FROM fm_vendor WHERE id='$vendor_id'";
			$this->db->query($sql,__LINE__,__FILE__);
			$this->db->next_record();

			$vendor_info= array
			(
				'org_nr' => $this->db->f('org_nr'),
				'konto_nr' => $this->db->f('konto_nr')
			);

			return $vendor_info;
		}

		protected function get_order_info($order_id='')
		{
			$order_info = array();
			$sql = "SELECT type FROM fm_orders WHERE id='$order_id'";
			$this->db->query($sql,__LINE__,__FILE__);
			$this->db->next_record();

			switch($this->db->f('type'))
			{
				case 'workorder':
					$sql2 = "SELECT title, category FROM fm_workorder WHERE id='$order_id'";
					$this->db->query($sql2,__LINE__,__FILE__);
					$this->db->next_record();
					$order_info['title'] = $this->db->f('title');
					$cat_id = (int)$this->db->f('category');
					$category = $this->cats->return_single($cat_id);
					$category_arr = explode('-',$category[0]['name']);
					$order_info['category'] = (int)trim($category_arr[0]);
					break;
				case 's_agreement':
					$sql2 = "SELECT descr as title FROM fm_s_agreement WHERE id='$order_id'";
					$this->db->query($sql2,__LINE__,__FILE__);
					$this->db->next_record();
					$order_info['title'] = $this->db->f('title');
					break;
			}

			return $order_info;
		}


		protected function select_invoice_rollback($date, $Filnavn,$rollback_voucher,$rollback_internal_voucher)
		{
			$date_array = phpgwapi_datetime::date_array($date);
	 		$day = $date_array['day'];
	 		$month = $date_array['month'];
	 		$year = $date_array['year'];

			switch($GLOBALS['phpgw_info']['server']['db_type'])
			{
				case 'mssql':
					$datepart_year 		= "datepart(year,overftid)";
					$datepart_month 	= "datepart(month,overftid)";
					$datepart_day 		= "datepart(day,overftid)";
					break;
				case 'mysql':
					$datepart_year 		= "YEAR(overftid)";
					$datepart_month 	= "MONTH(overftid)";
					$datepart_day 		= "DAYOFMONTH(overftid)";
					break;
				case 'pgsql':
					$datepart_year 		= "date_part('year',overftid)";
					$datepart_month 	= "date_part('month',overftid)";
					$datepart_day 		= "date_part('day',overftid)";
					break;
				case 'postgres':
					$datepart_year 		= "date_part('year',overftid)";
					$datepart_month 	= "date_part('month',overftid)";
					$datepart_day 		= "date_part('day',overftid)";
					break;
			}

			if($rollback_voucher)
			{
				$rollback_voucher = (int)$rollback_voucher;
				$sql="SELECT * FROM fm_ecobilagoverf WHERE bilagsnr_ut = {$rollback_voucher} AND manual_record IS NULL";
			}
			else if($rollback_internal_voucher)
			{
				$rollback_internal_voucher = (int)$rollback_internal_voucher;
				$sql="SELECT * FROM fm_ecobilagoverf WHERE bilagsnr = {$rollback_internal_voucher} AND manual_record IS NULL";
			}
			else
			{
				$sql="SELECT * FROM fm_ecobilagoverf WHERE filnavn='$Filnavn' AND $datepart_year=$year AND $datepart_month=$month AND $datepart_day= $day";
			}
			$this->db->query($sql,__LINE__,__FILE__);

			$invoice_rollback = array();
			while ($this->db->next_record())
			{
				$invoice_rollback[] = array
				(
					'id'					=> $this->db->f('id'),
					'bilagsnr'				=> $this->db->f('bilagsnr'),
					'bilagsnr_ut'			=> $this->db->f('bilagsnr_ut'),
					'kidnr'					=> $this->db->f('kidnr'),
					'typeid'				=> $this->db->f('typeid'),
					'kildeid'				=> $this->db->f('kildeid'),
					'pmwrkord_code'			=> $this->db->f('pmwrkord_code'),
					'belop'					=> $this->db->f('belop'),
					'fakturadato'			=> $this->db->f('fakturadato'),
					'periode'				=> $this->db->f('periode'),
					'periodization'			=> $this->db->f('periodization'),
					'periodization_start'	=> $this->db->f('periodization_start'),
					'forfallsdato'			=> $this->db->f('forfallsdato'),
					'fakturanr'				=> $this->db->f('fakturanr'),
					'spbudact_code'			=> $this->db->f('spbudact_code'),
					'regtid'				=> $this->db->f('regtid'),
					'artid'					=> $this->db->f('artid'),
					'godkjentbelop'			=> (int) $this->db->f('godkjentbelop') == 0 ? $this->db->f('belop') :  $this->db->f('godkjentbelop'),//restore original amount
					'spvend_code'			=> $this->db->f('spvend_code'),
					'dima'					=> $this->db->f('dima'),
					'loc1'					=> $this->db->f('loc1'),
					'dimb'					=> $this->db->f('dimb'),
					'mvakode'				=> $this->db->f('mvakode'),
					'dimd'					=> $this->db->f('dimd'),
					'dime'					=> $this->db->f('dime'),
					'project_id'			=> $this->db->f('project_id'),
					'kostra_id'				=> $this->db->f('kostra_id'),
					'item_type'				=> $this->db->f('item_type'),
					'item_id'				=> $this->db->f('item_id'),
					'oppsynsmannid'			=> $this->db->f('oppsynsmannid'),
					'saksbehandlerid'		=> $this->db->f('saksbehandlerid'),
					'budsjettansvarligid'	=> $this->db->f('budsjettansvarligid'),
					'oppsynsigndato'		=> $this->db->f('oppsynsigndato'),
					'saksigndato'			=> $this->db->f('saksigndato'),
		//			'budsjettsigndato'		=> $this->db->f('budsjettsigndato'), // må anvises på nytt etter tilbakerulling
					'merknad'				=> $this->db->f('merknad',true),
					'line_text'				=> $this->db->f('line_text',true),
					'splitt'				=> $this->db->f('splitt'),
					'ordrebelop'			=> $this->db->f('ordrebelop'),
		//			'utbetalingid'			=> $this->db->f('utbetalingid'),
		//			'utbetalingsigndato'	=> $this->db->f('utbetalingsigndato'),
					'external_ref'			=> $this->db->f('external_ref'),
					'external_voucher_id'	=> $this->db->f('external_voucher_id'),
					'currency'				=> $this->db->f('currency'),
					'process_log'			=> $this->db->f('process_log',true),
					'process_code'			=> $this->db->f('process_code'),

				);
			}

			return $invoice_rollback;
		}

		//rollback function
		protected function bilag_update_overf($BilagOverf)
		{
			$values= array
			(
				$BilagOverf['project_id'],
				$BilagOverf['kostra_id'],
				$BilagOverf['pmwrkord_code'],
				$BilagOverf['bilagsnr'],
				$BilagOverf['bilagsnr_ut'],
				$BilagOverf['splitt'],
				$BilagOverf['kildeid'],
				$BilagOverf['kidnr'],
				$BilagOverf['typeid'],
				$BilagOverf['fakturadato'],
				$BilagOverf['forfallsdato'],
				$BilagOverf['regtid'],
				$BilagOverf['artid'],
				$BilagOverf['spvend_code'],
				$BilagOverf['dimb'],
				$BilagOverf['oppsynsmannid'],
				$BilagOverf['saksbehandlerid'],
				$BilagOverf['budsjettansvarligid'],
				$BilagOverf['fakturanr'],
				$BilagOverf['spbudact_code'],
				$BilagOverf['dima'],
				$BilagOverf['loc1'],
				$BilagOverf['dimd'],
				$BilagOverf['dime'],
				$BilagOverf['mvakode'],
				$BilagOverf['periode'],
				$BilagOverf['periodization'],
				$BilagOverf['periodization_start'],
				$this->db->db_addslashes($BilagOverf['merknad']),
				$this->db->db_addslashes($BilagOverf['line_text']),
				$BilagOverf['utbetalingid'],
				$BilagOverf['oppsynsigndato'],
				$BilagOverf['saksigndato'],
				$BilagOverf['budsjettsigndato'],
				$BilagOverf['utbetalingsigndato'],
				$BilagOverf['item_type'],
				$BilagOverf['item_id'],
				$BilagOverf['external_ref'],
				$BilagOverf['external_voucher_id'],
				$BilagOverf['belop'],
				$BilagOverf['godkjentbelop'],
				$BilagOverf['currency'],
				$this->db->db_addslashes($BilagOverf['process_log']),
				$BilagOverf['process_code'],
			);

			$values	= $this->db->validate_insert($values);

			$sql= "INSERT INTO fm_ecobilag (project_id,kostra_id,pmwrkord_code,bilagsnr,bilagsnr_ut,splitt,kildeid,kidnr,typeid,"
			. " fakturadato,forfallsdato,regtid,artid,spvend_code,dimb,oppsynsmannid,"
			. " saksbehandlerid,budsjettansvarligid,fakturanr,spbudact_code,dima,loc1,dimd,dime,mvakode,"
			. " periode,periodization,periodization_start,merknad,line_text,utbetalingid,oppsynsigndato,saksigndato,budsjettsigndato,utbetalingsigndato,"
			. " item_type,item_id,external_ref,external_voucher_id,belop,godkjentbelop,currency,process_log,process_code)"
			. " VALUES ({$values})";

			$this->db->query($sql,__LINE__,__FILE__);
		}

		public function overfor($download,$force_period_year='')
		{
//			$download = 'on';
//			$download = False;
//			$this->debug=True;

			//Generer batch ID
			$batchid = $this->soXport->next_batchid();
			if ($download=='on')
			{
				$this->increment_batchid();
				//Lagre melding
				$this->log_start($batchid);
			}

			//Velg ut alle hoved bilag som skal overføres
			$vouchers = $this->select_vouchers_to_transfer();

			foreach ($vouchers as $voucher_id)
			{
				$receipt['message'][]= array('msg' => $this->transfer_voucher($batchid, $voucher_id, $download, $force_period_year));
			}

			if($this->connection)
			{
				switch ($this->config->config_data['common']['method'])
				{
					case 'ftp';
						ftp_quit($this->connection);
						break;
					case 'ssh';
						ssh2_exec($this->connection, 'exit');
						break;
				}
			}
			//Lagre melding
			if ($download=='on')
			{
				$this->log_end($batchid); //Lagre melding
			}

			if(!$vouchers)
			{
				$receipt['message'][]= array('msg' => 'Ingen bilag funnet for overføring');				
			}
			return $receipt;
		}

		protected function errorhandler($batchid,$error_desr)
		{
			if($this->db->get_transaction())
			{
				$this->db->transaction_abort();
			}

			$meld = $error_desr;

			//Vis feilmelding
			echo $meld;

			//Lagre feilmelding
			$this->log_error($batchid,$error_desr);
		}

		public function RullTilbake($Filnavn, $date,$rollback_voucher,$rollback_internal_voucher)
		{
			$voucher = $this->select_invoice_rollback($date, $Filnavn,$rollback_voucher,$rollback_internal_voucher);

			if ( $this->db->get_transaction() )
			{
				$this->global_lock = true;
			}
			else
			{
				$this->global_lock = false;
				$this->db->transaction_begin();
			}

			foreach ($voucher as $line)
			{
				$this->bilag_update_overf($line);

				if($line['pmwrkord_code'])
				{
					$orders_affected[$line['pmwrkord_code']] = true;

					$Belop = sprintf("%01.2f", $line['ordrebelop'])*100;

					if ($line['dimd'] % 2 == 0)
					{
						$actual_cost_field='act_mtrl_cost';
					}
					else
					{
						$actual_cost_field='act_vendor_cost';
					}

					$operator='-';

					$this->soXport->correct_actual_cost($line['pmwrkord_code'],$Belop,$actual_cost_field,$operator);
				}

				//Slett fra avviks tabell
			//	$this->soXport->delete_avvik($line['bilagsnr']);

				//Slett fra arkiv
				$this->soXport->delete_invoice($line['bilagsnr']);
			}

			$antall = count($voucher);
			if($antall > 0)
			{
				$fil_katalog = $this->config->config_data['export']['path'];

				if($rollback_voucher || $rollback_internal_voucher)
				{
					if ( !$this->global_lock )
					{
						$this->db->transaction_commit();
					}

					$receipt['message'][]= array('msg' => $antall . ' ' . lang('bilag/underbilag rullet tilbake'));
				}
				else if(unlink ($fil_katalog. '/' . $Filnavn))
				{
					if ( !$this->global_lock )
					{
						$this->db->transaction_commit();
					}

					$receipt['message'][]= array('msg' => $antall . ' ' . lang('bilag/underbilag rullet tilbake'));
					$receipt['message'][]= array('msg' => lang('File %1 is deleted',$Filnavn));
				}
				else
				{
					$this->db->transaction_abort();
					$receipt['error'][]= array('msg' => 'Noe gikk galt!');
				}
			}
			else
			{
				if ( !$this->global_lock )
				{
					$this->db->transaction_commit();
				}

				$receipt['error'][]= array('msg' => lang('Sorry - No hits'));
			}
			return $receipt;
		}

		protected function LagFilnavn($ref = '')
		{
			if(!$ref)
			{
				throw new Exception('Agresso_X114::LagFilnavn() Mangler SCANNINGNO' );
		//		throw new Exception('Agresso_X114::LagFilnavn() Mangler KEY' );
			}
			$fil_katalog = $this->config->config_data['export']['path'];

			$Filnavn = $fil_katalog . "/x114_{$this->client_code}_OK_{$ref}.xml";

			//Sjekk om filen eksisterer
			if (file_exists($Filnavn))
			{
				unlink($Filnavn);
			}

			return $Filnavn;
		}

		protected function transfer_voucher($batchid, $voucher_id, $download, $force_period_year = '')
		{
			$oRsBilag =  $this->soXport->get_voucher($voucher_id);

			$skip_agresso = false;
			//FIXME
			if(!isset($oRsBilag[0]['external_ref'])  || !$oRsBilag[0]['external_ref'])
			{
				$skip_agresso = true;
			}

			//Bestem filnavn
			
			try
			{
				$Filnavn = $this->LagFilnavn($oRsBilag[0]['external_ref']);
			//	$Filnavn = $this->LagFilnavn($oRsBilag[0]['external_voucher_id']);
			}
			catch(Exception $e)
			{
				if ( $e )
				{
					$message = $e->getMessage();
					$this->errorhandler($batchid,$message);
					return $message;
				}
			}

			//Test om filen kan opprettes og skrives til
			if(!$skip_agresso)
			{
				if (@fopen($Filnavn, "wb"))
				{
					unlink($Filnavn);
				}
				else
				{
					$message='kan ikke lagre til fil: '. $Filnavn .'<br>';
					if($this->debug)
					{
						echo $message;
					}
					else
					{
						return $message;
					}
				}
			}

			$antall = count($oRsBilag);

			if ( $this->db->get_transaction() )
			{
				$this->global_lock = true;
			}
			else
			{
				$this->db->transaction_begin();
			}

			$bilagsnr_ut = $oRsBilag[0]['bilagsnr_ut'];
			if(!$bilagsnr_ut)
			{
				$get_bilagsnr_ut = false;
				foreach ($oRsBilag as $line)
				{
					if(abs($line['godkjentbelop']) > 0)
					{
						$get_bilagsnr_ut = true;
					}
				}

				if($get_bilagsnr_ut)
				{
					$bilagsnr_ut = $this->increment_voucher_id();
				}
			}

			$purchaseorderstatus = 'OK';
			if(!$bilagsnr_ut)
			{
				$Filnavn = str_replace('_OK_', '_E_', $Filnavn);
				$purchaseorderstatus = 'Feil';
			}
			
			$tranfser_bilag = $bilagsnr_ut ? array($bilagsnr_ut) : array($voucher_id);

			$localtime = phpgwapi_datetime::user_localtime();

			$transactioninformation = array
			(
				0 => array
				(
					'TRANSACTIONTYPE' => 'X114',
					'TRANSFER' => array
					(
						0 => array
						(
							'TRANSFERDATE' => date('d.m.Y', $localtime),//28.05.2009
							'TRANSFERTIME' => date('H:i:s', $localtime)//14:29:52
						)
					)
				)
			);

			$invoiceheader = array
			(
				0 => array
				(
					'TRANSACTIONTYPE'			=> 'X114',
					'KEY'						=> $oRsBilag[0]['external_voucher_id'], //dummy
					'VOUCHERID'					=> $bilagsnr_ut,
					'INVNUM'					=> $oRsBilag[0]['fakturanr'],
					'INVDAT'					=> date('d.m.Y', strtotime($oRsBilag[0]['fakturadato'])), //DD.MM.YYYY
					'DUEDAT'					=> date('d.m.Y', strtotime($oRsBilag[0]['forfallsdato'])),//DD.MM.YYYY
					'SCANNINGNO'				=> $oRsBilag[0]['external_ref'], // 11E28NJINL3VR6
					'PROFILE'					=> 'TRAINVPOMA',
					'CLIENT.CODE'				=> $this->client_code, //14,
					'POATTRIB1'					=> '', //dummy
					'POATTRIB2'					=> '', //dummy
					'POPURCHASER'				=> '', //dummy
					'PREVOUCHERID'				=> '', //dummy
					'PURCHASEORDERNO'			=> $oRsBilag[0]['order_id'], // 1409220008
					'PURCHASEORDEROWNER.CODE'	=> $oRsBilag[0]['spvend_code'], // 100644
					'PURCHASEORDERSTATUS.CODE'	=> $purchaseorderstatus,
					'GENERALCOMMENT'			=> $comment, // Denne er fakturert i 3 deler OBS OBS!
				)
			);

			$accountline = array();

			if ( $oRsBilag[0]['periode'] )
			{
				if((int)$this->min_period < (int)$oRsBilag[0]['periode'])
				{
					$periode = $this->min_period;
				}
				else
				{
					$periode = $oRsBilag[0]['periode'];
				}
			}
			else if (isset($this->config->config_data['export']['dato_aarsavslutning']) && time() < $this->config->config_data['export']['dato_aarsavslutning'] )
			{
				if(date('Y',time()) == date('Y', $this->config->config_data['export']['dato_aarsavslutning']))
				{
					$periode = date('Y',time()) - 1 . '12';
				}
				else
				{
					$periode = date('Ym',time());
				}	
			}
			else
			{
				$time = time();

				if ( date('j',$time) < 7 ) //Day of the month without leading zeros
				{
					$time = $time - (7 * 24 * 3600);
				}
				
				$periode = date('Ym',$time);
			}

			$sum_amount = 0;
			$comment = array();
			foreach ($oRsBilag as $line)
			{
				if($line['process_log'])
				{
					$comment[] = "{$line['belop']}::{$line['process_log']}";
				}

				$BelopFelt = 'godkjentbelop';

				$amount =  $line[$BelopFelt] * 100;
				$amount =  number_format($amount,0,'','');

				if($line['order_id'])
				{
					$orders_affected[$line['order_id']] = true;

					//Oppdater beløp på arbeidsordre
					if ($download=='on')
					{
						if ($line['dimd'] % 2 == 0)
						{
							$actual_cost_field='act_mtrl_cost';
						}
						else
						{
							$actual_cost_field='act_vendor_cost';
						}
						$operator='+';

						if(!$this->debug)
						{
							$this->soXport->correct_actual_cost($line['order_id'],$amount, $actual_cost_field,$operator);
						}
					}
				}

				$oRsOverfBilag					= $line;
				$oRsOverfBilag['filnavn']		= $Filnavn? basename($Filnavn) : date('d.m.Y-H:i:s', phpgwapi_datetime::user_localtime());
				$oRsOverfBilag['ordrebelop']	= $line[$BelopFelt];
				$oRsOverfBilag['pmwrkord_code']	= $line['order_id'];
				$oRsOverfBilag['bilagsnr_ut']	= $bilagsnr_ut;
				$oRsOverfBilag['periode']		= $periode;

				if($line['dime'])
				{
					$category		= $this->cats->return_single($line['dime']);
					$category_arr	= explode('-',$category[0]['name']);
					$dim6			= (int)trim($category_arr[0]);
				}
				else
				{
					$dim6			= '';				
				}

				//Kopier verdier  til fm_ecobilagoverf
				if ($download=='on' && !$this->debug)
				{
					$this->soXport->add_OverfBilag($oRsOverfBilag);
				}

				if ($line['order_id'])
				{
					$order_info = $this->get_order_info($line['order_id']);
					if(!$dim6)
					{
						$dim6 = isset($order_info['category']) && $order_info['category'] ? $order_info['category'] : '';
					}
				}

				$descr = '';
				if($line['line_text'])
				{
					$descr = substr($line['line_text'],0,60);
				}
				else if ($line['order_id'])
				{
					$descr = substr($order_info['title'],0,60);
				}

				$sum_amount += $amount;
				$accountline[] = array
				(
					'TRANSACTIONTYPE'		=> 'R114',
					'ACCOUNTLINK.CODE'		=> $line['spbudact_code'], // 4180
					'CURRENCY'				=> $line['currency'],
					'AMOUNT'				=> $amount, // 312500
					'TAXCODE'				=> $line['mvakode'],
					'APPROVER.FULLNAME'		=> $line['budsjettansvarligid'], //Batch 04 - 14
					'DIMENSION.D1.CODE'		=> $line['dimb'], // 1111
					'DIMENSION.D2.CODE'		=> '',//$line['dima'], // 62000
					'DIMENSION.D3.CODE'		=> '',
					'DIMENSION.D4.CODE'		=> $line['project_id'], // dummy
					'DIMENSION.D5.CODE'		=> $dim5, // dummy
					'DIMENSION.D6.CODE'		=> $dim6, // dummy
					'DIMENSION.D7.CODE'		=> $dim7, // dummy
					'DIMENSION.D8.CODE'		=> $dim8, // dummy
					'POITEMDESCRIPTION'		=> $descr, // Sugerør,plast,fleksibelt,20cm
					'POITEMNUMBER'			=> $itemnumber, //200200
					'POITEMTYPE'			=> 'C', // A = Item, B = Special Product (SP), C = Text based  (Misc.)
					'POLINENUMBER'			=> $linenumber, // 10
					'RECEIVER.FULLNAME'		=> $line['budsjettansvarligid'], // Batch 04 - 14
					'STATUS'				=> 5,
					'SUBACCOUNT'			=> $periode, //200905 Accounting period YYYYMM
					'ALLOCATION.KEY'		=> $line['periodization'],//0
					'ALLOCATION.PERIOD'		=> $line['periodization_start'] //dummy
				);

			}

			if($accountline)
			{
				$accountline[] = array
				(
					'TRANSACTIONTYPE'		=> 'R114',
					'ACCOUNTLINK.CODE'		=> 2400,
					'CURRENCY'				=> $oRsBilag[0]['currency'],
					'AMOUNT'				=> (-1 * $sum_amount),
					'TAXCODE'				=> $oRsBilag[0]['mvakode'],
					'APPROVER.FULLNAME'		=> '',
					'DIMENSION.D1.CODE'		=> '',
					'DIMENSION.D2.CODE'		=> '',
					'DIMENSION.D3.CODE'		=> '',
					'DIMENSION.D4.CODE'		=> '',
					'DIMENSION.D5.CODE'		=> '',
					'DIMENSION.D6.CODE'		=> '',
					'DIMENSION.D7.CODE'		=> '',
					'DIMENSION.D8.CODE'		=> '',
					'POITEMDESCRIPTION'		=> '',
					'POITEMNUMBER'			=> '',
					'POITEMTYPE'			=> 'C',
					'POLINENUMBER'			=> '',
					'RECEIVER.FULLNAME'		=> '',
					'STATUS'				=> 5,
					'SUBACCOUNT'			=> '',
					'ALLOCATION.KEY'		=> '',
					'ALLOCATION.PERIOD'		=> '',
				);
			}

			$invoiceheader[0]['GENERALCOMMENT'] = implode("\n",$comment);
			$invoices = array
			(
				0 => array
				(
					'INVOICE' => array
					(
						0 => array
						(
							'INVOICEHEADER' => $invoiceheader,
							'ACCOUNTLINES' => array
							(
								0 => array
								(
									'ACCOUNTLINE' => $accountline
								)
							)
						)
					)
				)
			);

			$export_data = array
			(
				'TRANSACTIONINFORMATION'	=> $transactioninformation,
				'INVOICES'					=> $invoices
			);

			$xmltool = CreateObject('phpgwapi.xmltool');

			$buffer = $xmltool->import_var('INVOICEIMPORT', $export_data,true, true);
			$buffer = str_replace('<INVOICEIMPORT>', '<INVOICEIMPORT TYPE="INVOICE">', $buffer);

			//Slett bilaget i fm_ecobilag
			if ($download=='on' && !$this->debug)
			{
				$this->_delete_from_fm_ecobilag($voucher_id);
				//Logg transaksjon
				$this->soXport->log_transaction($batchid,$voucher_id,lang('Invoice transferred'));
			}

			//Fullfør transaksjon
			if ($download=='on' && !$this->debug)
			{
			//	$file_written = true;

			// -- Start
			 
				if($skip_agresso)
				{
					if ( !$this->global_lock )
					{
						$this->db->transaction_commit();
					}
					$message = "Antall bilag/underbilag overført til historikk (ikke til Agresso): {$antall}";
					return $message;
				}

				$file_written = false;
				$fp = fopen($Filnavn, "wb");
				fwrite($fp,$buffer);

				if(fclose($fp))
				{
					$file_written=true;
				}

			// -- END
				if( $file_written && ($this->config->config_data['common']['method'] != 'ftp' && $this->config->config_data['common']['method'] != 'ssh'))
				{
					$transfer_ok = true;
				}
				else if($file_written)
				{
					$transfer_ok = $this->transfer($buffer,$Filnavn,$batchid,$tranfser_bilag);
				}

				if($transfer_ok)
				{
					$this->soXport->update_actual_cost_from_archive($this->orders_affected);

					if ( !$this->global_lock )
					{
						$this->db->transaction_commit();
					}

					$message = "Antall bilag/underbilag overfort: {$antall}, fil: {$Filnavn}";
				}
				else
				{
					$this->db->transaction_abort();
					$message = 'Noe gikk galt med overforing av godkjendte fakturaer!';
				}
			}
			else
			{
				$message = $buffer;
				$this->db->transaction_abort();

			}

			return $message;
		}

		protected function increment_voucher_id()
		{
			$name = 'bilagsnr_ut';
			$now = time();
			$this->db->query("SELECT value, start_date FROM fm_idgenerator WHERE name='{$name}' AND start_date < {$now} ORDER BY start_date DESC");
			$this->db->next_record();
			$next_id = $this->db->f('value') +1;
			$start_date = (int)$this->db->f('start_date');
			$this->db->query("UPDATE fm_idgenerator SET value = $next_id WHERE name = '{$name}' AND start_date = {$start_date}");

			return $next_id;
		}

		protected function _delete_from_fm_ecobilag($bilagsnr)
		{
			$bilagsnr = (int) $bilagsnr;
			$sql="DELETE FROM fm_ecobilag WHERE bilagsnr = $bilagsnr";
			$this->db->query($sql,__LINE__,__FILE__);
		}

		protected function transfer($buffer,$Filnavn,$batchid,$tranfser_bilag)
		{
			$transfer_ok = false;
			if($this->config->config_data['common']['method']=='ftp' || $this->config->config_data['common']['method']=='ssh')
			{
				if(!$connection = $this->connection)
				{
					$connection	= $this->phpftp_connect();
				}

				$basedir = $this->config->config_data['export']['remote_basedir'];
				if($basedir)
				{
					$remote_file = $basedir . '/' . basename($Filnavn);
				}
				else
				{
					$remote_file = basename($Filnavn);
				}

				switch ($this->config->config_data['common']['method'])
				{
					case 'ftp';
						$transfer_ok = ftp_put($connection,$remote_file, $Filnavn, FTP_BINARY);
						break;
					case 'ssh';
						$sftp = ssh2_sftp($connection);
						$stream = @fopen("ssh2.sftp://$sftp$remote_file", 'w');
						$data_to_send = @file_get_contents($Filnavn);
						fwrite($stream, $data_to_send);
						$transfer_ok = @fclose($stream);
						break;
					default:
						$transfer_ok = false;
				}
				if ($transfer_ok)
				{
				 	for ($i=0;$i<count($tranfser_bilag);$i++)
					{
						$this->soXport->log_transaction($batchid,$tranfser_bilag[$i],lang('Invoice transferred %1 to Agresso',basename($Filnavn)));
					}
				}
				else
				{
				 	for ($i=0;$i<count($tranfser_bilag);$i++)
					{
						$this->soXport->log_transaction($batchid,$tranfser_bilag[$i],lang('Failed to transfere %1 to Agresso',basename($Filnavn)));
					}
				}
				if(!$transfer_ok)
				{
					unlink($Filnavn);
				}
			}
			return 	$transfer_ok;
		}

		protected function phpftp_connect() 
		{
			$server				= $this->config->config_data['common']['host'];
			$user				= $this->config->config_data['common']['user'];
			$password			= $this->config->config_data['common']['password'];
			$port				= 22;

			switch ($this->config->config_data['common']['method'])
			{
				case 'ftp';
					if($connection = ftp_connect($server))
					{
						ftp_login($connection,$user,$password);
					}
					break;
				case 'ssh';
					if (!function_exists("ssh2_connect"))
					{
						die("function ssh2_connect doesn't exist");
					}
					if(!($connection = ssh2_connect("$server", $port)))
					{
						$message = "fail: unable to establish connection";
						_debug_array($message);
						//$receipt['error'][]= array('msg' => $message);
					}
					else
					{
						// try to authenticate with username root, password secretpassword
						if(!ssh2_auth_password($connection, $user, $password))
						{
							$message = "fail: unable to authenticate";
							_debug_array($message);
							//$receipt['error'][]= array('msg' => $message);
						}
					}
					break;
			}
			$this->connection = $connection;
			return $connection;
		}
	}
