Patch level :2.1 nopatch
Files correlati :ba3.exe Ricompilazione Demo : [ ] Commento : rimessa la stampa tabelle senza report (con i vecchi rpt! uno schifo) git-svn-id: svn://10.65.10.50/trunk@12323 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
46af6bbe70
commit
8a8d1a91a8
20
ba/ba3.cpp
20
ba/ba3.cpp
@ -7,25 +7,25 @@ int main(int argc, char** argv)
|
||||
switch (r)
|
||||
{
|
||||
case 1:
|
||||
ba3200(argc,argv); break; //Stampa tabelle
|
||||
ba3200(argc,argv); break;
|
||||
case 2:
|
||||
ba3300(argc,argv); break; //Stampa fogli libri bollati
|
||||
ba3300(argc,argv); break;
|
||||
case 3:
|
||||
ba3400(argc,argv); break; //Programma di test per le maschere
|
||||
ba3400(argc,argv); break;
|
||||
case 4:
|
||||
ba3500(argc,argv); break; //Tabelle libro unico
|
||||
ba3500(argc,argv); break;
|
||||
case 5:
|
||||
ba3600(argc,argv); break; //Stampa indici libro unico
|
||||
ba3600(argc,argv); break;
|
||||
case 6:
|
||||
ba3700(argc,argv); break; //Condizioni di pagamento
|
||||
ba3700(argc,argv); break;
|
||||
case 7:
|
||||
ba3800(argc,argv); break; //Stampa tabelle IV direttiva CEE
|
||||
ba3800(argc,argv); break;
|
||||
case 8:
|
||||
ba3900(argc,argv); break; //Gestione indici libro unico
|
||||
ba3900(argc,argv); break;
|
||||
case 9:
|
||||
ba3a00(argc,argv); break; //Stampa condizioni di pagamento
|
||||
ba3a00(argc,argv); break;
|
||||
default:
|
||||
ba3100(argc,argv); break; //Gestione tabelle
|
||||
ba3100(argc,argv); break;
|
||||
}
|
||||
exit(0);
|
||||
return 0;
|
||||
|
574
ba/ba3200.cpp
574
ba/ba3200.cpp
@ -1,107 +1,531 @@
|
||||
//Programma per stampa report tabelle
|
||||
// ba3200 Stampa tabelle
|
||||
//
|
||||
// legge un file con estensione .rpt che descrive la stampa.
|
||||
// Vedi file leggimi.txt per il formato del file
|
||||
//
|
||||
|
||||
#include <applicat.h>
|
||||
#include <relation.h>
|
||||
#include <reprint.h>
|
||||
#include <mask.h>
|
||||
#include <printapp.h>
|
||||
#include <tabutil.h>
|
||||
#include <utility.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TTable_report
|
||||
///////////////////////////////////////////////////////////
|
||||
#include <nditte.h>
|
||||
|
||||
class TTable_report : public TReport
|
||||
#include "ba3.h"
|
||||
#include "ba3200.h"
|
||||
|
||||
#define FOOTER_LEN 4 // se non ridefinito nel .rpt
|
||||
|
||||
class BA3200_application : public TPrintapp
|
||||
{
|
||||
TString _tabname;
|
||||
TFilename _rptname;
|
||||
TScanner *_rpt;
|
||||
TFilename _maskname;
|
||||
TMask *_msk;
|
||||
TRelation *_rel;
|
||||
TCursor *_cur;
|
||||
int _logicnum;
|
||||
TString_array _string_roman, _string_compound;
|
||||
TString_array _field_roman, _field_compound;
|
||||
bool _stampa_registri;
|
||||
bool _stampa_ca7; //tabella causali 770
|
||||
bool _tabella_comune;
|
||||
|
||||
protected:
|
||||
virtual bool execute_prescript();
|
||||
TString& get_rpt_name(TString& t) const;
|
||||
TString& get_mask_name(TString& t) const;
|
||||
void destroy_objects();
|
||||
|
||||
public:
|
||||
|
||||
virtual bool user_create() ;
|
||||
virtual bool user_destroy() ;
|
||||
virtual bool set_print(int) ;
|
||||
|
||||
virtual void set_page(int, int);
|
||||
virtual bool preprocess_page (int, int);
|
||||
virtual bool preprocess_print(int file, int counter);
|
||||
|
||||
void set_headers();
|
||||
void set_rows();
|
||||
void set_footers();
|
||||
void set_translations();
|
||||
void set_relations();
|
||||
BA3200_application(): _rpt(NULL), _msk(NULL), _rel(NULL), _cur(NULL) {}
|
||||
virtual ~BA3200_application() {}
|
||||
};
|
||||
|
||||
bool TTable_report::execute_prescript()
|
||||
|
||||
TString& BA3200_application::get_mask_name(TString& t) const
|
||||
{
|
||||
TFilename msk = filename().name();
|
||||
msk.ext(""); msk.lower();
|
||||
TMask m(msk);
|
||||
CHECK(_rel,"Can't use a NULL relation to retrieve table module");
|
||||
TTable& tab = (TTable&) _rel->lfile(_tabname);
|
||||
|
||||
TString8 m = _tabname;
|
||||
if (m[0] == '%')
|
||||
m.ltrim(1);
|
||||
|
||||
const bool ok = m.run() == K_ENTER;
|
||||
if (ok)
|
||||
t = tab.module();
|
||||
t << "st" << m;
|
||||
t.upper();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
TString& BA3200_application::get_rpt_name(TString& t) const
|
||||
{
|
||||
CHECK(_rel,"Can't use a NULL relation to retrieve table module");
|
||||
TTable& tab = (TTable&) _rel->lfile(_tabname);
|
||||
|
||||
TString16 m = _tabname;
|
||||
if (m[0] == '%') m.ltrim(1);
|
||||
|
||||
t = tab.module();
|
||||
t << "tb" << m;
|
||||
t.upper();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
bool BA3200_application::set_print(int)
|
||||
{
|
||||
TRectype from(_rel->lfile().curr()); from.zero();
|
||||
TRectype to (from);
|
||||
|
||||
if (_msk->run() == K_ENTER)
|
||||
{
|
||||
TRectype rec_fr(LF_TAB), rec_to(LF_TAB);
|
||||
for (int i = 0; i < m.fields(); i++)
|
||||
const int campi_maschera = _msk->fields();
|
||||
for (int i = 0; i < campi_maschera; i++)
|
||||
{
|
||||
const TMask_field& fld = m.fld(i);
|
||||
const TFieldref* fr = fld.field();
|
||||
if (fr != NULL)
|
||||
const TMask_field& campo_maschera = _msk->fld(i);
|
||||
const char* val = campo_maschera.get();
|
||||
if (*val)
|
||||
{
|
||||
if (fld.in_group(1))
|
||||
fr->write(fld.get(), rec_fr);
|
||||
if (fld.in_group(2))
|
||||
fr->write(fld.get(), rec_to);
|
||||
const TFieldref* campo_ref = campo_maschera.field();
|
||||
|
||||
if (campo_ref != NULL && campo_ref->ok())
|
||||
{
|
||||
TDate d;
|
||||
const bool is_date_field = campo_maschera.class_id() == CLASS_DATE_FIELD;
|
||||
if (is_date_field)
|
||||
d=val;
|
||||
if (campo_maschera.in_group(1)) campo_ref->write(is_date_field ? d.string(ANSI) : val, from);
|
||||
else
|
||||
if (campo_maschera.in_group(2)) campo_ref->write(is_date_field ? d.string(ANSI) : val, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TString use = recordset()->query_text();
|
||||
|
||||
const TString& cod_fr = rec_fr.get("CODTAB");
|
||||
if (cod_fr.not_empty())
|
||||
use << "\nFROM CODTAB='" << cod_fr << '\'';
|
||||
_cur->setregion (from, to);
|
||||
|
||||
const TString& cod_to = rec_to.get("CODTAB");
|
||||
if (cod_to.not_empty())
|
||||
use << "\nTO CODTAB='" << cod_to << '\'';
|
||||
set_headers();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
set_recordset(use);
|
||||
void BA3200_application::set_page (int , int )
|
||||
{
|
||||
_string_roman.destroy();
|
||||
_field_roman.destroy();
|
||||
_string_compound.destroy();
|
||||
_field_compound.destroy();
|
||||
set_rows();
|
||||
}
|
||||
|
||||
bool BA3200_application::preprocess_page(int , int)
|
||||
{
|
||||
const int items = _field_roman.items();
|
||||
|
||||
if (items > 0)
|
||||
{
|
||||
for (int i = 0; i < items; i++)
|
||||
{
|
||||
TString& fn = _field_roman.row(i);
|
||||
TFieldref fld(fn, 0);
|
||||
TString& s = _string_roman.row(i);
|
||||
|
||||
const int n = atoi(fld.read(*_rel));
|
||||
s = itor(n);
|
||||
}
|
||||
}
|
||||
|
||||
const int compound = _field_compound.items();
|
||||
if (compound > 0)
|
||||
// Scorre le righe settate
|
||||
for (int i = 0; i < compound; i++)
|
||||
{
|
||||
TToken_string f(_field_compound.row(i),'+'); // campo composto
|
||||
TString& s = _string_compound.row(i); // riga da stampare
|
||||
s.cut(0); // Reset the row...
|
||||
bool compile_row = TRUE;
|
||||
const int cmp_items = f.items();
|
||||
// Scorre gli elementi della riga
|
||||
for (int j = 0; j < cmp_items; j++)
|
||||
{
|
||||
// compone la stringa totale
|
||||
TString xx(f.get(j));
|
||||
if (xx[0] != '"') // se non e' una costante stringa legge il valore
|
||||
{
|
||||
TFieldref fld(xx,0);
|
||||
xx = fld.read(*_rel);
|
||||
if (xx.empty()) compile_row = FALSE;
|
||||
else compile_row = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xx.ltrim(1);xx.rtrim(1);
|
||||
}
|
||||
if (compile_row)
|
||||
s << xx; // appende alla stringa il valore ricavato (se il campo e' vuoto non appende nemmeno la stringa fissa)
|
||||
}
|
||||
}
|
||||
// Stampa tabella registri. Calcolo: pagine residue = pagine - stampate
|
||||
if (_stampa_registri)
|
||||
{
|
||||
const int pagine = _cur->file().get_int("I2");
|
||||
const int stampate = _cur->file().get_int("I1");
|
||||
const int residue = pagine - stampate;
|
||||
if (residue > 0)
|
||||
set_row(1, "@126g%4d", residue);
|
||||
else
|
||||
set_row(1, "@126g%4s", " ");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BA3200_application::set_headers()
|
||||
{
|
||||
TString NomeTabella, sep, formato_intesta, testo_intesta;
|
||||
int LungRiga, riga_intesta=0, last_riga=1;
|
||||
TToken_string line;
|
||||
TString256 riga;
|
||||
|
||||
reset_header ();
|
||||
|
||||
_rpt->paragraph("Headers");
|
||||
|
||||
// Leggo la lunghezza della riga (usata per centrare l'intestazione)
|
||||
line = _rpt->line();
|
||||
LungRiga = line.get_int();
|
||||
|
||||
riga.spaces(LungRiga);
|
||||
// Senno' nella stampa a 80 non ci sta ditta e data
|
||||
|
||||
// Leggo il nome della tabella
|
||||
line = _rpt->line();
|
||||
NomeTabella = line.get();
|
||||
|
||||
// Sulla prima riga di intestazione metto la ditta, la data e la pagina
|
||||
if (!_tabella_comune)
|
||||
{
|
||||
const long codditta = get_firm();
|
||||
TString80 ragsoc;
|
||||
TLocalisamfile nditte(LF_NDITTE);
|
||||
|
||||
nditte.zero();
|
||||
nditte.put(NDT_CODDITTA, codditta);
|
||||
if (nditte.read() == NOERR)
|
||||
{
|
||||
ragsoc = nditte.get(NDT_RAGSOC);
|
||||
if (LungRiga < 100) ragsoc.cut(40);
|
||||
}
|
||||
riga.overwrite(format(FR("Ditta %4ld %s"), codditta,(const char *)ragsoc));
|
||||
}
|
||||
|
||||
if (_stampa_ca7)
|
||||
{
|
||||
TDate d (_msk->get(F_DATASTAMPA));
|
||||
printer().setdate(d);
|
||||
}
|
||||
|
||||
riga.overwrite (FR("Data @> Pag. @#"), riga.len()-25);
|
||||
|
||||
set_header (last_riga++, "%s", (const char *)riga);
|
||||
|
||||
// Centro il nome della tabella
|
||||
// Per la stampa registri non va centrato.
|
||||
// Lo lascio anche per le altre stampe
|
||||
// if (_stampa_registri)
|
||||
NomeTabella.left_just (LungRiga);
|
||||
/* else
|
||||
NomeTabella.center_just (LungRiga); */
|
||||
if (_stampa_ca7)
|
||||
NomeTabella.center_just (LungRiga);
|
||||
|
||||
set_header (last_riga++, "@b%s", (const char *)NomeTabella);
|
||||
|
||||
// Aggiungo una riga vuota per separare prima intestazione
|
||||
//sep.fill ('-', LungRiga);
|
||||
//set_header (last_riga, "%s", (const char *)sep);
|
||||
|
||||
line = _rpt->line();
|
||||
while ( (line != "") && (line[0] != '[') )
|
||||
{
|
||||
riga_intesta = atoi (line.get());
|
||||
formato_intesta = line.get();
|
||||
testo_intesta = (const char *) line.get();
|
||||
if (riga_intesta)
|
||||
set_header (last_riga+riga_intesta, (const char *)formato_intesta,
|
||||
(const char *)testo_intesta);
|
||||
line = _rpt->line();
|
||||
}
|
||||
|
||||
if (riga_intesta) last_riga += riga_intesta;
|
||||
last_riga++;
|
||||
|
||||
//set_header (last_riga, (const char *)sep);
|
||||
sep.fill(' ');
|
||||
set_header (last_riga, (const char *)sep);
|
||||
set_background(format("W2l{1,3,%d,3}l{1,%d,%d,%d}", LungRiga, last_riga, LungRiga, last_riga));
|
||||
}
|
||||
|
||||
void BA3200_application::set_rows()
|
||||
{
|
||||
TToken_string line;
|
||||
TFieldref campo;
|
||||
int from = 0, to= 0,riga_record;
|
||||
TString formato_campo, picture;
|
||||
const char * name = "";
|
||||
|
||||
_rpt->paragraph("Rows");
|
||||
|
||||
line = _rpt->line();
|
||||
while ( (line != "") && (line[0] != '[') )
|
||||
{
|
||||
riga_record = line.get_int();
|
||||
|
||||
|
||||
TString s(line.get());
|
||||
int logicnum = _logicnum;
|
||||
const bool is_compound = s.find('+') >= 0; // Controlla se e' una stringa composta (usare #t nel formato)
|
||||
if (!is_compound)
|
||||
{
|
||||
campo = s;
|
||||
from = campo.from();
|
||||
to = campo.to();
|
||||
name = campo.name();
|
||||
if (campo.file() != 0)
|
||||
logicnum = campo.file();
|
||||
}
|
||||
|
||||
formato_campo = line.get();
|
||||
formato_campo.trim();
|
||||
formato_campo.lower();
|
||||
const int p = formato_campo.find("@m");
|
||||
|
||||
if (p != -1 && !is_compound)
|
||||
{
|
||||
formato_campo.cut(p);
|
||||
formato_campo << "#t";
|
||||
_string_roman.add("");
|
||||
_field_roman.add(s);
|
||||
const int last = _string_roman.items() - 1;
|
||||
|
||||
set_row (riga_record, formato_campo, _string_roman.objptr(last));
|
||||
}
|
||||
else if (!is_compound)
|
||||
{
|
||||
if (formato_campo.find("@pn") >= 0)
|
||||
picture = line.get();
|
||||
else
|
||||
picture = "";
|
||||
|
||||
if (to == -1)
|
||||
if (picture != "")
|
||||
set_row (riga_record, formato_campo, FLD(logicnum,name,picture) );
|
||||
else
|
||||
set_row (riga_record, formato_campo, FLD(logicnum,name) );
|
||||
else
|
||||
set_row (riga_record, formato_campo, FLD(logicnum,name,from,to) );
|
||||
}
|
||||
else
|
||||
{
|
||||
_string_compound.add("");
|
||||
_field_compound.add(s);
|
||||
const int last = _string_compound.items() - 1;
|
||||
//versione speciale per la stampa della tabella Note clienti!
|
||||
if (_tabname == "%NOT")
|
||||
{
|
||||
//deve costruire la stampa tenendo conto anche dei return
|
||||
|
||||
TString stringone;
|
||||
TRectype& rec = current_cursor()->curr();
|
||||
TString4 fieldname;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
fieldname.format("S%d", i);
|
||||
stringone << rec.get(fieldname);
|
||||
}
|
||||
stringone.replace((char)0xB6, '\n');
|
||||
|
||||
TParagraph_string para(stringone, 75);
|
||||
for (int r = 0; r < para.items(); r++)
|
||||
set_row(riga_record + r, "@3g%s", para.get());
|
||||
|
||||
//mette a TRUE la variabile _force_setpage delle printapp in modo da richiamare la set_rows() ad ogni cambio record
|
||||
force_setpage();
|
||||
}
|
||||
else
|
||||
set_row (riga_record, formato_campo, _string_compound.objptr(last));
|
||||
}
|
||||
line = (const char *) _rpt->line();
|
||||
}
|
||||
}
|
||||
|
||||
void BA3200_application::set_footers()
|
||||
{
|
||||
TToken_string line;
|
||||
int footer_len, riga;
|
||||
TString formato, testo;
|
||||
|
||||
reset_footer();
|
||||
|
||||
_rpt->paragraph("Footers");
|
||||
|
||||
line = _rpt->line();
|
||||
footer_len = line.get_int();
|
||||
if (footer_len != 0)
|
||||
{
|
||||
printer().footerlen(footer_len);
|
||||
line = _rpt->line();
|
||||
}
|
||||
while ( (line != "") && (line[0] != '[') )
|
||||
{
|
||||
riga = line.get_int();
|
||||
formato = line.get();
|
||||
testo = line.get();
|
||||
set_footer (riga, (const char *)formato, (const char*)testo);
|
||||
line = _rpt->line();
|
||||
}
|
||||
}
|
||||
|
||||
void BA3200_application::set_translations()
|
||||
{
|
||||
TString campo, from, to;
|
||||
TToken_string line;
|
||||
int logicnum;
|
||||
|
||||
_rpt->paragraph("Translations");
|
||||
|
||||
line = _rpt->line();
|
||||
while ( (line != "") && (line[0] != '[') )
|
||||
{
|
||||
logicnum = line.get_int();
|
||||
campo = line.get();
|
||||
from = line.get();
|
||||
to = line.get();
|
||||
set_translation (logicnum, (char*)(const char *)campo, (char*)(const char *)from, (char*)(const char *)to);
|
||||
line = _rpt->line();
|
||||
}
|
||||
}
|
||||
|
||||
void BA3200_application::set_relations()
|
||||
{
|
||||
TToken_string line("", ';');
|
||||
TString tab(16), expr(40);
|
||||
int key, linkto, alias, logicnum;
|
||||
|
||||
_rpt->paragraph("Relations");
|
||||
|
||||
line = _rpt->line();
|
||||
while ( (line != "") && (line[0] != '[') )
|
||||
{
|
||||
tab = line.get();
|
||||
logicnum = atoi(tab);
|
||||
expr = line.get();
|
||||
key = line.get_int();
|
||||
if (key == 0) key = 1;
|
||||
linkto = line.get_int();
|
||||
alias = line.get_int();
|
||||
if (logicnum > 0)
|
||||
_rel->add(logicnum, expr, key, linkto, alias);
|
||||
else
|
||||
_rel->add(tab, expr, key, linkto, alias);
|
||||
|
||||
line = _rpt->line();
|
||||
}
|
||||
}
|
||||
bool BA3200_application::user_create()
|
||||
{
|
||||
bool ok=TRUE;
|
||||
|
||||
_tabname = argv(2);
|
||||
_tabname.upper();
|
||||
|
||||
_tabella_comune = (_tabname[0] == '%');
|
||||
|
||||
// Flag per la stampa tabella registri
|
||||
_stampa_registri = (_tabname == "REG");
|
||||
_stampa_ca7 = (_tabname == "%CA7");
|
||||
|
||||
_rel = new TRelation (_tabname);
|
||||
_cur = new TCursor (_rel);
|
||||
|
||||
TString16 t;
|
||||
t = _tabname.right(3);
|
||||
_maskname << get_mask_name(t) << ".msk";
|
||||
if (!_maskname.exist())
|
||||
ok = error_box(FR("Impossibile aprire la maschera di stampa %s"), (const char *)_maskname);
|
||||
else
|
||||
_msk = new TMask (_maskname) ;
|
||||
if (ok)
|
||||
{
|
||||
t = _tabname.right(3);
|
||||
_rptname << get_rpt_name(t) << ".rpt" ;
|
||||
if (!_rptname.exist())
|
||||
ok = error_box(FR("Impossibile aprire il report di stampa %s"), (const char *)_rptname);
|
||||
else
|
||||
{
|
||||
_rpt = new TScanner(_rptname);
|
||||
|
||||
|
||||
add_cursor (_cur);
|
||||
add_file (_tabname);
|
||||
|
||||
_logicnum = _cur->file().num();
|
||||
|
||||
reset_print ();
|
||||
|
||||
printer().footerlen (FOOTER_LEN);
|
||||
for (int i=1; i <= FOOTER_LEN; i++) set_footer(i, "%s", " ");
|
||||
|
||||
#ifdef DBG1
|
||||
set_fillchar ('.');
|
||||
#endif
|
||||
set_relations();
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
destroy_objects() ;
|
||||
return ok;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TTable_reporter
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TTable_reporter : public TSkeleton_application
|
||||
{
|
||||
protected:
|
||||
virtual void main_loop();
|
||||
|
||||
public:
|
||||
bool get_rpt_name(TFilename& rptname) const;
|
||||
};
|
||||
|
||||
|
||||
bool TTable_reporter::get_rpt_name(TFilename& rptname) const
|
||||
bool BA3200_application::preprocess_print(int file, int counter)
|
||||
{
|
||||
TTable tab(argv(2));
|
||||
rptname = tab.module();
|
||||
rptname << "st" << tab.get("COD");
|
||||
rptname.ext("rep");
|
||||
rptname.lower();
|
||||
set_headers();
|
||||
set_footers();
|
||||
set_translations();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return rptname.custom_path();
|
||||
void BA3200_application::destroy_objects()
|
||||
{
|
||||
if (_msk) delete _msk;
|
||||
// if (_cur) delete _cur; // Deleted by printapp!
|
||||
if (_rel) delete _rel;
|
||||
}
|
||||
|
||||
void TTable_reporter::main_loop()
|
||||
bool BA3200_application::user_destroy()
|
||||
{
|
||||
TFilename rptname;
|
||||
if (get_rpt_name(rptname))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
TTable_report rep; rep.load(rptname);
|
||||
TReport_book book;
|
||||
if (book.add(rep))
|
||||
book.print_or_preview();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
error_box(FR("Manca il file %s"), (const char *)rptname);
|
||||
destroy_objects() ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int ba3200(int argc, char* argv[])
|
||||
{
|
||||
TTable_reporter app;
|
||||
app.run(argc, argv, TR("Stampa Report Tabelle"));
|
||||
{
|
||||
BA3200_application a;
|
||||
a.run(argc, argv, TR("Stampa tabella"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user