<?xml version="1.0" encoding="ISO-8859-1" ?>
<%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>
<%!	static final String pageName = "popup_waiting_invoice" ; %>

<%@ include file="popup_initialize.jsp"%>

<%
// Get the error in the request
KeyWordingList errors = (KeyWordingList)request.getAttribute("error");

// Get request variables
String invoiceAction 	= (String) request.getParameter("invoice.action");
String invoiceNumber 	= (String) request.getParameter("invoice.invoicenumber");
String isWaiting 		= "true";
int timeout 			= 0;

if (invoiceAction != null && !invoiceAction.equals("init")){
	// Get session variables
	isWaiting = (String) session.getAttribute("invoice.waiting");
	timeout  = ((Integer) session.getAttribute("invoice.invoiceTimeout")).intValue() + 1;
}
%>

<html>
<head>
	<title><%=title%></title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="Expires" content="-1">
	<link rel="stylesheet" href="<%=styleSheet%>" type="text/css">	
	<script type="text/javascript" src="<%=javaScript%>functions.js"></script>
	<script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
</head>
<script type="text/javascript">
<!--
<% /* 
if the invoice number is not found in the request, get it from session
if (invoiceNumber==null) {
	invoiceNumber = (String)session.getAttribute("invoice.invoicenumber");
}

// Manage the popup closing
if (isWaiting != null && isWaiting.equals("false")){
	// if no error, close immediatly
	%>self.close();<%
} 
else {
	%>setTimeout('self.close()',5000);<% 
} */%>
-->

</script>
<% // if timeout is over, or an error occured, stop submit the form %>
<body>
<center>
<% 
if (errors != null) {
	String errorMessage = null;
		for (int i = 0; i < errors.size(); i++) {
			KeyWording error = errors.elementAt(i);
			errorMessage = error.getWording();
		} 
%>
	<table border="0" width="100%" height="100%">
		<tr>
			<td>&nbsp;</td>
			<td>
				<img src="<%=commonPathImage%>sign_error.gif" width="24" height="24">
			</td>
			<td><b class="textred"><%=errorMessage%></b></td>
		</tr>
	</table>
<% } else { %>
	<table border="0" width="100%" height="100%">
	<tr>
		<td width="100%" height="100%" valign="center" align="center">
			<img src="<%=pathImage%>waiting.gif" border="0" vspace="0" hspace="0" >
		</td>
	</tr>
	</table>
<% } %>
</center>
</body>
</html><%	//*****     Common variables %>