issue #0000559 : Ajout support préliminaire pour la suppression, duplication de toutes les annonces.

This commit is contained in:
Michael RICOIS 2011-03-17 11:25:59 +00:00
parent 0d562a7d5a
commit 5d9322c52d
5 changed files with 312 additions and 133 deletions

View File

@ -12,41 +12,131 @@ class Annonces
public function __construct($annonces = array())
{
if (is_array($annonces) && count($annonces)>0){
if (is_array($annonces) && count($annonces)>0) {
$this->annonces = $annonces;
$this->triAnnonces();
}
}
public function getAnnonceHead($ann)
public function getAnnonceDesc($ann)
{
if ($this->isBalo($ann['BodaccCode']))
{
if ($this->isBodacc($ann['BodaccCode'])) {
$tabSource = explode('-', $ann['BodaccCode']);
$source = $tabSource[0];
$idSource = $tabSource[1];
if ($source[0] == 'B') {
$logo = 'img/logo_jo.png';
if ($ann['BodaccNum']==0){
$libelle = 'Source BODACC '.substr($ann['BodaccCode'],-1).
' du '.$this->dateAnnonce($ann['DateParution']);
} else {
$libelle = 'Source BODACC n°'.$ann['BodaccNum'].' '.
substr($ann['BodaccCode'],-1).
' du '.$this->dateAnnonce($ann['DateParution']).
'. Département n°'.$ann['Departement'].
'. <a href="/?page=competences&siret='.
$_SESSION['tabInfo']['entrep']['siret'].
'&type=tri">'.$ann['Tribunal'].'</a>';
}
}elseif ($source[0] == 'G' || $source[0] == 'T'){
$logo = './img/logo_greffe.png';
$libelle = 'Source Greffe du Tribunal';
}elseif ($source[0] == 'P'){
$logo = './img/logo_inpi.png';
$libelle = 'Source Registre National du Commerce';
}else{
$logo = './img/logo_jal.png';
$libelle = '';
if( hasModeEdition() &&
(substr($source,0,2)=='JT' || $source=='ANTE') ){
$libelle = '<b>Source TESSI</b> - ';
}
$libelle.= 'Source Journal Annonces L&eacute;gales';
}
return '<img src="'.$logo.'" /> '.$libelle.'.';
} elseif ($this->isBalo($ann['BodaccCode'])) {
return 'BALO n&deg;'.$ann['BodaccNum'].' du '.
$this->dateAnnonce($ann['DateParution']).'.';
} elseif ($this->isAsso($ann['BodaccCode'])) {
return 'J.O. ASSOCIATION n&deg;'.$ann['BodaccNum'].' du '.
$this->dateAnnonce($ann['DateParution']).'.';
} elseif ($this->isBomp($ann['BodaccCode'])){
return 'Annonce n&deg;'.$ann['NumAnnonce'] . '. ' .
'Source ' . $ann['BodaccCode'] . ' ' .
'n&deg;' . ($ann['BodaccNum']*1) . ' ' .
' du '.$this->dateAnnonce($ann['DateParution']).
'. D&eacute;partement n&deg;'.$ann['Departement'].'.';
} else {
}
elseif ($this->isAsso($ann['BodaccCode']))
{
}
elseif ($this->isBomp($ann['BodaccCode']))
{
}
elseif ($this->isBodacc($ann['BodaccCode']))
{
}
else
{
}
}
public function getAnnonceTexte($id)
public function getAnnonceEntree($ann)
{
if ($this->isBodacc($ann['BodaccCode'])) {
if ($ann['dateInsertionSD']!='') {
return ' - Entr&eacute;e en base : '.
$this->dateAnnonce($ann['dateInsertionSD']);
}
} elseif ($this->isBalo($ann['BodaccCode'])) {
return 'Entr&eacute; n&deg;'.$ann['NumAnnonce'].'.';
} elseif ($this->isAsso($ann['BodaccCode'])) {
return 'Annonce n&deg;'.$ann['NumAnnonce'].'.';
} elseif ($this->isBomp($ann['BodaccCode'])){
return '';
} else {
}
}
public function getAnnonceEntreeSD($ann)
{
if ($this->isBodacc($ann['BodaccCode'])) {
} elseif ($this->isBalo($ann['BodaccCode'])) {
return 'Entr&eacute;e en base S&amp;D : '.
$this->dateAnnonce($ann['dateInsertionSD']).'.';
} elseif ($this->isAsso($ann['BodaccCode'])) {
return 'Entr&eacute;e en base S&amp;D : '.
$this->dateAnnonce($ann['dateInsertionSD']).'.';
} elseif ($this->isBomp($ann['BodaccCode'])){
return '';
} else {
}
}
public function getAnnonceEven($ann)
{
$output = '';
foreach ($ann['evenements'] as $i=>$even) {
$output.= $even['LibEven'].'<br/>';
}
return $output;
}
public function getAnnonceTexte($ann)
{
$pattern = "/((?:[0-9]{9,9})|(?:[0-9]{3,3} [0-9]{3,3} [0-9]{3,3})|(?:[0-9]{3,3}\.[0-9]{3,3}\.[0-9]{3,3})|(?:[0-9]{3,3}-[0-9]{3,3}-[0-9]{3,3}))/";
return preg_replace_callback($pattern, 'replace_siren', $ann['texteAnnonce']);
}
public function getAnnonceResume($ann)
@ -62,7 +152,7 @@ class Annonces
protected function hrefAnnonce($ann)
{
$href = false;
if ($this->isBodacc($ann['BodaccCode'])){
if ($this->isBodacc($ann['BodaccCode'])) {
$href = 'idan='.$ann['id'].'&vue=bodacc';
} elseif ($this->isBalo($ann['BodaccCode'])) {
$href = 'idan='.$ann['id'].'&vue=balo';
@ -76,11 +166,19 @@ class Annonces
return $href;
}
/**
* Retourne une date formatté
* @param unknown_type $date
*/
protected function dateAnnonce($date)
{
return WDate::dateT('Y-m-d', 'd/m/Y', $date);
}
/**
* logoAnnonce
* @param unknown_type $ann
*/
protected function logoAnnonce($ann)
{
$src = '';
@ -144,6 +242,10 @@ class Annonces
}
}
/**
* Retourne le libellé de l'annonce
* @param unknown_type $ann
*/
protected function libAnnonce($ann)
{
$lib = '';
@ -166,7 +268,10 @@ class Annonces
}
return $lib;
}
/**
* Tri les annonces en fonction de la source
*/
protected function triAnnonces()
{
foreach ($this->annonces as $i => $ann)
@ -174,6 +279,7 @@ class Annonces
if ($this->isBodacc($ann['BodaccCode'])){
$this->annoncesBodacc[] = $ann;
} elseif ($this->isBalo($ann['BodaccCode'])) {
$ann['texteAnnonce'] = utf8_decode($ann['texteAnnonce']);
$this->annoncesBalo[] = $ann;
} elseif ($this->isAsso($ann['BodaccCode'])) {
$this->annoncesAsso[] = $ann;
@ -185,6 +291,10 @@ class Annonces
}
}
/**
* Détermine si l'annonce est une annonce BODACC
* @param string $code
*/
protected function isBodacc($code)
{
if (in_array($code, array('BODA', 'BODB', 'BODC'))){
@ -194,6 +304,10 @@ class Annonces
}
}
/**
* Détermine si l'annonce est une annonce BALO
* @param string $code
*/
protected function isBalo($code)
{
if ($code == 'BALO'){
@ -203,6 +317,10 @@ class Annonces
}
}
/**
* Détermine si l'annonce est une annonce ASSO
* @param string $code
*/
protected function isAsso($code)
{
if ($code == 'ASSO'){
@ -212,6 +330,10 @@ class Annonces
}
}
/**
* Détermine si l'annonce est une annonce BOAMP
* @param string $code
*/
protected function isBomp($code)
{
if (in_array($code, array('BOMP A', 'BOMP B', 'BOMP C', 'MAPA'))){

View File

@ -31,6 +31,43 @@ function supprAnnonceCollecte($idan, $siret = ''){
return $output;
}
function supprAnnonce($source, $idan, $siret) {
global $client;
$sourceNum = null;
$source = strtoupper($source);
if (in_array($source, array('BODA', 'BODB', 'BODC'))){
$sourceNum = 1;
} elseif ($source == 'BALO') {
$sourceNum = 2;
} elseif ($source == 'ASSO') {
$sourceNum = 3;
} elseif (in_array($source, array('BOMP A', 'BOMP B', 'BOMP C', 'MAPA'))) {
$sourceNum = 4;
} elseif (!empty($source)){
$sourceNum = 0;
}
if ($sourceNum == null) {
return "Source inconnu";
}
try {
$O = $client->supprAnnonce($sourceNum, $idan, $siret);
$error = $O['error'];
} catch (SoapFault $fault) {
require_once 'soaperror.php';
processSoapFault($client, $fault, $_SESSION['tabInfo']);
}
if ( isset($error) && $error['errNum'] == 0 ){
$output = 'Annonce '.$idan.' supprimé !';
} elseif ( isset($error) && $error['errNum'] != 0 ) {
$output = 'Erreur lors de la suppression.';
} else {
$output = "Une erreur est survenue...";
}
return $output;
}
function dupliqueAnnonceCollecte($idan, $siret){
global $client;
try {
@ -52,21 +89,24 @@ function dupliqueAnnonceCollecte($idan, $siret){
switch ( $subaction ) {
case 'deleteDialog':
$idan = $params[2];
$siret = $params[3];
$source = $params[2];
$idan = $params[3];
$siret = $_SESSION['tabInfo']['entrep']['siret'];
?>
<div id="result">
Êtes-vous sur de vouloir supprimer l'annonce <?=$idan?> ?
Êtes-vous sur de vouloir supprimer l'annonce <?=$idan?>, source <?=$source?> ?
</div>
<form name="deleteDialog">
<input type="hidden" name="idan" value="<?=$idan?>" />
<input type="hidden" name="siret" value="<?=$siret?>" />
<input type="hidden" name="source" value="<?=$source?>" />
</form>
<?php
break;
case 'copyDialog':
$idan = $params[2];
$siret = $params[3];
$source = $params[2];
$idan = $params[3];
$siret = $_SESSION['tabInfo']['entrep']['siret'];
?>
<div id="result">
Affecte l'annonce <?=$idan?> de <?=$siret?> sur un nouveau siren.
@ -74,15 +114,18 @@ switch ( $subaction ) {
<br/>
<form name="copyDialog">
<input type="hidden" name="idan" value="<?=$idan?>" />
<input type="hidden" name="source" value="<?=$source?>" />
Siren / Siret : <input type="text" name="siret" value="" />
</form>
<?php
break;
case 'editDialog':
$inEditDialog = true;
$idan = $params[2];
$siret = $params[3]; FB::log($siret, 'siret');
$siren = substr($siret,0,9); FB::log($siren, 'siren');
$source = $params[2];
$idan = $params[3];
$siret = $_SESSION['tabInfo']['entrep']['siret'];
FB::log($siret, 'siret');
$siren = substr($siret,0,9);
$nic = substr($siret,10,5);
if ( !empty($idan) ) {
$idanResult = getAnnonceCollecte($idan, $siret);
@ -152,11 +195,14 @@ switch ( $subaction ) {
case 'delete':
$idan = $_REQUEST['idan'];
$siret = $_REQUEST['siret'];
echo supprAnnonceCollecte($idan, $siret);
$source = $_REQUEST['source'];
echo supprAnnonce($source, $idan, $siret);
break;
case 'copy':
$idan = $_REQUEST['idan'];
$siret = str_replace(' ','',$_REQUEST['siret']);
$source = $_REQUEST['source'];
//@todo : En attente pour utilisation nouvelle méthode
echo dupliqueAnnonceCollecte($idan, $siret);
break;
case 'edit':

View File

@ -0,0 +1,36 @@
<?php
if ( hasModeEdition() )
{
$href = '/?page=saisieajax&q=annonces';
$liensEdit = array(
'editDialog' => array(
'class' => 'annonceEdit',
'title' => 'Edition annonce',
'img' => '<img src="./img/interface/editer.png"/>',
),
'deleteDialog' => array(
'class' => 'annonceDelete',
'title' => 'Suppression annonce',
'img' => '<img src="./img/interface/supprimer.png"/>',
),
'copyDialog' => array(
'class' => 'annonceCopy',
'title' => 'Dupliquer sur autre Siren',
'img' => '<img src="./img/save_copy.png"/>',
),
);
foreach ( $liensEdit as $lienId => $lienItem ){
?>
<a class="<?=$lienItem['class']?>" title="<?=$lienItem['title']?>"
href="<?=$href.'/'.$lienId.'/'.$ann['BodaccCode'].'/'.$idan?>" />
<?=$lienItem['img']?>
</a>
<?php
}
?>
<script type="text/javascript" src="js/jquery.form.js"></script>
<script type="text/javascript" src="js/annonces.js"></script>
<?php
}

View File

@ -1,3 +1,16 @@
function annonceAction(action, source, idan, siret) {
$.post('index.php',
{
page: 'saisieajax',
q: 'annonces/'+action,
idan: idan,
siret: siret,
source: source
},
function(data){ return data; }
);
}
$(document).ready(function(){
//Gestion boite dialog mandataire
$('a.annonceDelete').click(function(e){
@ -17,12 +30,10 @@ $(document).ready(function(){
'Supprimer': function() {
var siret = $('input:hidden[name=siret]').val();
var idan = $('input:hidden[name=idan]').val();
$('#result').html("Patientez...., Suppression en cours....");
$.post('index.php',
{ page: 'saisieajax', q: 'annonces/delete',
idan: idan, siret: siret},
function(data){ $('#result').html(data); }
);
var source = $('input:hidden[name=source]').val();
$('#result').html("Suppression en cours....");
var data = annonceAction('delete', source, idan, siret);
$('#result').html(data);
},
'Quitter': function() { $(this).dialog('close'); }
},
@ -76,11 +87,10 @@ $(document).ready(function(){
'Dupliquer': function() {
var siret = $('input[name=siret]').val();
var idan = $('input:hidden[name=idan]').val();
$.post('index.php',
{ page: 'saisieajax', q: 'annonces/copy',
idan: idan, siret: siret},
function(data){ $('#result').html(data); }
);
var source = $('input:hidden[name=source]').val();
$('#result').html("Copie en cours....");
var data = annonceAction('copy', source, idan, siret);
$('#result').html(data);
},
'Quitter': function() { $(this).dialog('close'); }
},

View File

@ -1,7 +1,6 @@
<?php
if (!page_checkParams()) die('Paramètres incorrects !');
require_once 'cache/cache.php';
require_once 'partenaires/classMTva.php';
require_once 'partenaires/classMMap.php';
require_once 'partenaires/classMCoface.php';
@ -19,7 +18,6 @@ $message='';
//Récupération des infos du webservice
$annonces = scoresws_annonces($siret, $siren, $idEntreprise, $vue, $idan);
FB::log($annonces, 'annonces');
$objAnnonces = new Annonces($annonces);
?>
<div id="center">
@ -48,14 +46,11 @@ if ($message<>'') {
</tr>
<tr>
<td width="30">&nbsp;</td>
<td width="200" colspan="2" class="StyleInfoLib">
Raison Sociale
</td>
<td width="200" colspan="2" class="StyleInfoLib">Raison Sociale</td>
<td width="350" class="StyleInfoData">
<?=$raisonSociale?>
<?php
if(hasModeEdition())
{
if(hasModeEdition()) {
?>
<a href="./?page=saisie&siret=<?=$siret?>&idEntreprise=<?=$idEntreprise?>">
(Edition)
@ -69,26 +64,33 @@ if ($message<>'') {
<?php
if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
{
//Présélection des annonces
foreach($annonces as $ann){
if($ann['id']==$idan)
break;
}
FB::log($ann, 'ann');
// BALO
if ($vue=='balo')
{
//Présélection des annonces
foreach($objAnnonces->annoncesBalo as $ann) {
if($ann['id']==$idan)
break;
}
?>
<h2>BALO</h2>
<table>
<tr>
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoData">
BALO n&deg;<?=$ann['BodaccNum']?>&nbsp;du <?=WDate::dateT('Y-m-d','d/m/Y',$ann['DateParution'])?>.
Entr&eacute; n&deg;<?=$ann['NumAnnonce']?>.
Entr&eacute;e en base S&amp;D : <?=WDate::dateT('Y-m-d','d/m/Y',$ann['dateInsertionSD'])?>.
<br/>
<?php
echo $objAnnonces->getAnnonceDesc($ann).
$objAnnonces->getAnnonceEntree($ann).
$objAnnonces->getAnnonceEntreeSD($ann);
require_once 'saisie/saisie_liensdialog.php';
?>
</td>
</tr>
<tr>
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoData">
<a href="/?page=annonces&siret=<?=$siret?>&idEntreprise=<?=$idEntreprise?>&idan=<?=$_REQUEST['idan']?>&vue=balo&mode=pdf" target="_blank">
Cliquez ici pour voir cette annonce au format PDF&nbsp;(<?=adapteOCtets(@filesize(PATH_DATA.'/jo/balo/'.WDate::dateT('Y-m-d','Y',$ann['DateParution']).'/'. $ann['Lien_Annonce_Pdf']))?>)
</a>
@ -101,10 +103,13 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
<tr>
</table>
<?php
$ann['texteAnnonce']=utf8_decode($ann['texteAnnonce']);
}
elseif ($vue=='bodacc' || $vue=='abod')
{
foreach($objAnnonces->annoncesBodacc as $ann) {
if($ann['id']==$idan)
break;
}
?>
<h2>&Eacute;V&Eacute;NEMENTS L&Eacute;GAUX</h2>
<table>
@ -112,59 +117,12 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoData">
<?php
$tabSource=explode('-', $ann['BodaccCode']);
$source=$tabSource[0];
$idSource=@$tabSource[1];
if ($source[0] == 'B') {
$logo = 'img/logo_jo.png';
if ($ann['BodaccNum']==0){
$libelle = 'Source BODACC '.substr($ann['BodaccCode'],-1).
' du '.WDate::dateT('Y-m-d','d/m/Y',$ann['DateParution']);
} else {
$libelle = 'Source BODACC n&deg;'.$ann['BodaccNum'].'&nbsp;'.
substr($ann['BodaccCode'],-1).
' du '.WDate::dateT('Y-m-d','d/m/Y',$ann['DateParution']).
'. D&eacute;partement n&deg;'.$ann['Departement'].
'. <a href="/?page=competences&siret='.$siret.
'&type=tri">'.$ann['Tribunal'].'</a>';
}
}elseif ($source[0] == 'G' || $source[0] == 'T'){
$logo = './img/logo_greffe.png';
$libelle = 'Source Greffe du Tribunal';
echo $objAnnonces->getAnnonceDesc($ann).' '.
$objAnnonces->getAnnonceEntree($ann).' '.
$objAnnonces->getAnnonceEntreeSD($ann);
}elseif ($source[0] == 'P'){
$logo = './img/logo_inpi.png';
$libelle = 'Source Registre National du Commerce';
}else{
$logo = './img/logo_jal.png';
$libelle = '';
if( hasModeEdition() &&
(substr($source,0,2)=='JT' || $source=='ANTE') ){
$libelle = '<b>Source TESSI</b> - ';
}
$libelle.= 'Source Journal Annonces L&eacute;gales';
}
if ($ann['dateInsertionSD'] <> '') {
$libelle.= ' - Entr&eacute;e en base : ';
$date = new WDate;
$libelle.= $date->dateT('Y-m-d', 'd/m/Y', $ann['dateInsertionSD']);
}
$edition = '';
if ( hasModeEdition() ){
$edition.= ' <a class="annonceEdit" href="/?page=saisieajax&q=annonces/editDialog/'.
$idan.'/'.$siret.'" title="Edition annonce">'.
'<img src="./img/interface/editer.png"/></a>';
$edition.= ' <a class="annonceDelete" href="/?page=saisieajax&q=annonces/deleteDialog/'.
$idan.'/'.$siret.'"'.' title="Suppression annonce">'.
'<img src="./img/interface/supprimer.png"/></a>';
$edition.= ' <a class="annonceCopy" href="/?page=saisieajax&q=annonces/copyDialog/'.
$idan.'/'.$siret.'"'.' title="Dupliquer sur autre Siren ">'.
'<img src="./img/save_copy.png"/></a>';
$edition.= '<script type="text/javascript" src="js/jquery.form.js"></script>';
$edition.= '<script type="text/javascript" src="js/annonces.js"></script>';
}
require_once 'saisie/saisie_liensdialog.php';
?>
<?='<img src="'.$logo.'" />'?> <?=$libelle?> <?=$edition?>
</td>
</tr>
</table>
@ -172,15 +130,23 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
}
elseif ($vue=='asso')
{
foreach($objAnnonces->annoncesAsso as $ann) {
if($ann['id']==$idan)
break;
}
?>
<h2>Associations</h2>
<table>
<tr>
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoData">
J.O. ASSOCIATION n&deg;<?=$ann['BodaccNum']?>&nbsp;du <?=WDate::dateT('Y-m-d','d/m/Y',$ann['DateParution'])?>.
Annonce n&deg;<?=$ann['NumAnnonce']?>.
Entr&eacute;e en base S&amp;D : <?=WDate::dateT('Y-m-d','d/m/Y',$ann['dateInsertionSD'])?>.
<?php
echo $objAnnonces->getAnnonceDesc($ann).' '.
$objAnnonces->getAnnonceEntree($ann).' '.
$objAnnonces->getAnnonceEntreeSD($ann);
require_once 'saisie/saisie_liensdialog.php';
?>
</td>
</tr>
</table>
@ -188,6 +154,10 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
}
elseif ($vue=='bomp')
{
foreach($objAnnonces->annoncesBomp as $ann) {
if($ann['id']==$idan)
break;
}
?>
<h2>Marchés publics</h2>
<table>
@ -195,12 +165,11 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoData">
<?php
$libelle = 'Annonce n&deg;'.$ann['NumAnnonce'] . '. ' .
'Source ' . $ann['BodaccCode'] . ' ' .
'n&deg;' . ($ann['BodaccNum']*1) . ' ' .
' du '.WDate::dateT('Y-m-d','d/m/Y',$ann['DateParution']).
'. D&eacute;partement n&deg;'.$ann['Departement'].'.';
echo $libelle;
echo $objAnnonces->getAnnonceDesc($ann).' '.
$objAnnonces->getAnnonceEntree($ann).' '.
$objAnnonces->getAnnonceEntreeSD($ann);
require_once 'saisie/saisie_liensdialog.php';
?>
</td>
</tr>
@ -213,9 +182,7 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
<td width="30">&nbsp;</td>
<td width="550" colspan="3" class="StyleInfoLib">
<b>
<?php
foreach (@$ann['evenements'] as $i=>$even) { echo @$even['LibEven'].'<br/>'; }
?>
<?php echo $objAnnonces->getAnnonceEven($ann)?>
</b>
</td>
</tr>
@ -224,11 +191,9 @@ if ($idan && in_array($vue, array('bodacc', 'abod', 'balo', 'asso', 'bomp')))
</tr>
<tr>
<td width="30">&nbsp;</td>
<?php
/**Affichage du texte de l'annonce**/
$texte=preg_replace_callback("/((?:[0-9]{9,9})|(?:[0-9]{3,3} [0-9]{3,3} [0-9]{3,3})|(?:[0-9]{3,3}\.[0-9]{3,3}\.[0-9]{3,3})|(?:[0-9]{3,3}-[0-9]{3,3}-[0-9]{3,3}))/", 'replace_siren', $ann['texteAnnonce']);
?>
<td width="550" colspan="3"><code><?=$texte?></code></td>
<td width="550" colspan="3">
<code><?php echo $objAnnonces->getAnnonceTexte($ann)?></code>
</td>
</tr>
<tr><td colspan="4">&nbsp;</td></tr>
<tr>