<?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 14733 2016-02-12 14:14:26Z 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) 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;
		}

		/**
		 * Abort transaction and log to database
		 * @param integer $batchid
		 * @param string $error_desr
		 */
		protected function errorhandler( $batchid, $error_desr )
		{
			if ($this->db->get_transaction())
			{
				$this->db->transaction_abort();
			}

			//Vis feilmelding
			echo $error_desr;

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

		/**
		 * RullTilbake er initiert fra import-filteret
		 * @param string $Filnavn
		 * @param string $date
		 * @param integer $rollback_voucher
		 * @param integer $rollback_internal_voucher
		 * @return array Receipt
		 */
		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');
			}
			$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();

			$_periode = $oRsBilag[0]['periode'] ? $oRsBilag[0]['periode'] : date('Ym');

			if ((int)$this->min_period < (int)$_periode)
			{
				$periode = $this->min_period;
			}
			else
			{
				$periode = $_periode;
			}

			$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)
			{
				$this->db->query('SELECT category FROM fm_vendor WHERE id=' . (int)$oRsBilag[0]['spvend_code']);
				$this->db->next_record();
				$_vendor_category = $this->db->f('category');

				$accountline[] = array
					(
					'TRANSACTIONTYPE' => 'R114',
					'ACCOUNTLINK.CODE' => $_vendor_category == 1 ? 2400 : 2460,
					'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);
			if ($comment)
			{
				$invoiceheader[0]['PURCHASEORDERSTATUS.CODE'] .= " \n" . 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;
		}
	}