Patch level : 10.0
Files correlati : bacnv.exe Ricompilazione Demo : [ ] Commento : Aggiunta conversione profile e maschere delle vendite in modo da aggiornare la gestione di commessa/fase git-svn-id: svn://10.65.10.50/trunk@17123 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
3cd820072d
commit
34bbc4d456
512
ba/bacnv.cpp
512
ba/bacnv.cpp
@ -1,23 +1,15 @@
|
||||
#include <applicat.h>
|
||||
#include <assoc.h>
|
||||
#include <mailbox.h>
|
||||
#include <progind.h>
|
||||
#include <prefix.h>
|
||||
#include <relation.h>
|
||||
#include <reputils.h>
|
||||
#include <scanner.h>
|
||||
#include <sheet.h>
|
||||
#include <tabutil.h>
|
||||
#include <urldefid.h>
|
||||
#include <utility.h>
|
||||
#include <extcdecl.h>
|
||||
|
||||
|
||||
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32
|
||||
#include <direct.h>
|
||||
#define RMDIR _rmdir
|
||||
#else
|
||||
#define RMDIR rmdir
|
||||
#endif
|
||||
|
||||
#include <causali.h>
|
||||
#include <clifo.h>
|
||||
#include <mov.h>
|
||||
@ -140,13 +132,10 @@ void TConversione_xbase::update()
|
||||
end_wait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Applicazione di conversione archivi
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class TConversione_archivi : public TApplication
|
||||
{
|
||||
int _nconv;
|
||||
@ -158,7 +147,13 @@ protected: // TApplication
|
||||
virtual bool create() ;
|
||||
virtual bool destroy() ;
|
||||
virtual bool menu(MENU_TAG);
|
||||
|
||||
|
||||
// Metodi per convert_profile
|
||||
bool backup_text_file(TFilename& name, TLog_report& log) const;
|
||||
bool rinumera_paragrafo(const TFilename& ini, const char* paragrafo,
|
||||
const char* contatore, const char* variabile, TLog_report& log) const;
|
||||
bool rinumera_maschera(const TFilename& msk, TLog_report& log) const;
|
||||
|
||||
public:
|
||||
bool convert_rmov(TLocalisamfile & rmov, TArray & recs, int nrecs);
|
||||
void contropartita_rmov();
|
||||
@ -209,7 +204,7 @@ bool TConversione_archivi::create()
|
||||
TApplication::create();
|
||||
const int args = argc();
|
||||
|
||||
_nconv = atoi(argv(1));
|
||||
_nconv = args > 1 ? abs(atoi(argv(1))) : 0;
|
||||
if (_nconv > 1)
|
||||
{
|
||||
_oldditta = get_firm();
|
||||
@ -362,11 +357,13 @@ bool TConversione_archivi::menu(MENU_TAG)
|
||||
break;
|
||||
case 22:
|
||||
convert_pcon_ivd();
|
||||
break;
|
||||
case 23:
|
||||
convert_profile(argv(2));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -540,7 +537,7 @@ void TConversione_archivi::zero_770()
|
||||
for (int i = list.items()-1; i >= 0; i--)
|
||||
remove(list.row(i));
|
||||
list.destroy();
|
||||
RMDIR(format("%scom/770", __ptprf));
|
||||
xvt_fsys_rmdir(format("%scom/770", __ptprf));
|
||||
}
|
||||
if (fexist(format("%s770", __ptprf)))
|
||||
{
|
||||
@ -549,139 +546,136 @@ void TConversione_archivi::zero_770()
|
||||
for (int i = list.items()-1; i >= 0; i--)
|
||||
remove(list.row(i));
|
||||
list.destroy();
|
||||
RMDIR(format("%s770", __ptprf));
|
||||
xvt_fsys_rmdir(format("%s770", __ptprf));
|
||||
}
|
||||
}
|
||||
|
||||
void TConversione_archivi::convert_patty()
|
||||
{
|
||||
{
|
||||
TTable ivd("%IVD");
|
||||
ivd.zero();
|
||||
ivd.put("CODTAB", "9E0023");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
ivd.put("CODTAB", "9E 23");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
ivd.put("CODTAB", "9E 23");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
}
|
||||
{
|
||||
TTable doc("%TPD");
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "AN");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "IN");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "PG");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "NA");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "NC");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
{
|
||||
doc.put("S0", "Nota di credito");
|
||||
doc.put("I0", "9");
|
||||
doc.rewrite();
|
||||
TTable ivd("%IVD");
|
||||
ivd.zero();
|
||||
ivd.put("CODTAB", "9E0023");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
ivd.put("CODTAB", "9E 23");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
ivd.put("CODTAB", "9E 23");
|
||||
if (ivd.read(_isequal, _lock) == NOERR)
|
||||
ivd.remove();
|
||||
}
|
||||
}
|
||||
TAssoc_array causarr;
|
||||
|
||||
TDir d;
|
||||
d.get(LF_CAUSALI,_nolock,_nordir,_sysdirop);
|
||||
if (d.is_com())
|
||||
d.get(LF_CAUSALI,_nolock,_comdir);
|
||||
|
||||
if (d.eod() > 0L)
|
||||
{
|
||||
TLocalisamfile caus(LF_CAUSALI);
|
||||
for (caus.first(_lock); caus.good(); caus.next(_lock))
|
||||
{
|
||||
const TString16 tpd(caus.get("TIPODOC"));
|
||||
const TString16 incimm(caus.get("CODCAUSIM"));
|
||||
|
||||
if (incimm.not_empty())
|
||||
causarr.add(incimm, incimm);
|
||||
if (tpd == "AN") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "IN") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "PG") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "NA") caus.put("TIPODOC","NC");
|
||||
|
||||
caus.rewrite();
|
||||
}
|
||||
}
|
||||
const bool topatch = causarr.items() > 0;
|
||||
|
||||
d.get(LF_MOV);
|
||||
if (d.eod() > 0L)
|
||||
{
|
||||
TLocalisamfile mov(LF_MOV);
|
||||
|
||||
for (mov.first(_lock); mov.good(); mov.next(_lock))
|
||||
{
|
||||
const TString16 tpd(mov.get("TIPODOC"));
|
||||
if (topatch)
|
||||
TTable doc("%TPD");
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "AN");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "IN");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "PG");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "NA");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
doc.remove();
|
||||
doc.zero();
|
||||
doc.put("CODTAB", "NC");
|
||||
if (doc.read(_isequal, _lock) == NOERR)
|
||||
{
|
||||
const TString16 codcaus(mov.get("CODCAUS"));
|
||||
|
||||
if (causarr.objptr(codcaus) != NULL)
|
||||
{
|
||||
mov.zero("DATA74TER");
|
||||
mov.zero("REG");
|
||||
mov.zero("PROTIVA");
|
||||
mov.zero("UPROTIVA");
|
||||
mov.zero("REGST");
|
||||
mov.zero("TIPO");
|
||||
mov.zero("CODCF");
|
||||
mov.zero("TOTDOC");
|
||||
mov.zero("RITFIS");
|
||||
mov.zero("RITSOC");
|
||||
mov.zero("PROVVIS");
|
||||
mov.zero("CODVALI");
|
||||
mov.zero("CAMBIOI");
|
||||
mov.zero("CORRLIRE");
|
||||
mov.zero("CORRVALUTA");
|
||||
mov.zero("OCFPI");
|
||||
mov.zero("CODPAG");
|
||||
}
|
||||
doc.put("S0", "Nota di credito");
|
||||
doc.put("I0", "9");
|
||||
doc.rewrite();
|
||||
}
|
||||
if (tpd == "AN") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "IN") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "PG") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "NA") mov.put("TIPODOC","NC");
|
||||
mov.rewrite();
|
||||
}
|
||||
}
|
||||
{
|
||||
}
|
||||
TAssoc_array causarr;
|
||||
|
||||
}
|
||||
if (_codditta == 0)
|
||||
{
|
||||
TDir d;
|
||||
TSystemisamfile f(LF_FORM);
|
||||
TFilename lf;
|
||||
|
||||
d.get(LF_FORM);
|
||||
lf.format("%sstd/lf0054.txt", __ptprf);
|
||||
if (fexist(lf) && fexist(d.filename()))
|
||||
f.load(lf);
|
||||
}
|
||||
d.get(LF_CAUSALI,_nolock,_nordir,_sysdirop);
|
||||
if (d.is_com())
|
||||
d.get(LF_CAUSALI,_nolock,_comdir);
|
||||
|
||||
if (d.eod() > 0L)
|
||||
{
|
||||
TLocalisamfile caus(LF_CAUSALI);
|
||||
for (caus.first(_lock); caus.good(); caus.next(_lock))
|
||||
{
|
||||
const TString16 tpd(caus.get("TIPODOC"));
|
||||
const TString16 incimm(caus.get("CODCAUSIM"));
|
||||
|
||||
if (incimm.not_empty())
|
||||
causarr.add(incimm, incimm);
|
||||
if (tpd == "AN") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "IN") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "PG") caus.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "NA") caus.put("TIPODOC","NC");
|
||||
|
||||
caus.rewrite();
|
||||
}
|
||||
}
|
||||
const bool topatch = causarr.items() > 0;
|
||||
|
||||
d.get(LF_MOV);
|
||||
if (d.eod() > 0L)
|
||||
{
|
||||
TLocalisamfile mov(LF_MOV);
|
||||
|
||||
for (mov.first(_lock); mov.good(); mov.next(_lock))
|
||||
{
|
||||
const TString16 tpd(mov.get("TIPODOC"));
|
||||
if (topatch)
|
||||
{
|
||||
const TString16 codcaus(mov.get("CODCAUS"));
|
||||
|
||||
if (causarr.objptr(codcaus) != NULL)
|
||||
{
|
||||
mov.zero("DATA74TER");
|
||||
mov.zero("REG");
|
||||
mov.zero("PROTIVA");
|
||||
mov.zero("UPROTIVA");
|
||||
mov.zero("REGST");
|
||||
mov.zero("TIPO");
|
||||
mov.zero("CODCF");
|
||||
mov.zero("TOTDOC");
|
||||
mov.zero("RITFIS");
|
||||
mov.zero("RITSOC");
|
||||
mov.zero("PROVVIS");
|
||||
mov.zero("CODVALI");
|
||||
mov.zero("CAMBIOI");
|
||||
mov.zero("CORRLIRE");
|
||||
mov.zero("CORRVALUTA");
|
||||
mov.zero("OCFPI");
|
||||
mov.zero("CODPAG");
|
||||
}
|
||||
}
|
||||
if (tpd == "AN") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "IN") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "PG") mov.zero("TIPODOC");
|
||||
else
|
||||
if (tpd == "NA") mov.put("TIPODOC","NC");
|
||||
mov.rewrite();
|
||||
}
|
||||
}
|
||||
if (_codditta == 0)
|
||||
{
|
||||
TDir d;
|
||||
TSystemisamfile f(LF_FORM);
|
||||
TFilename lf;
|
||||
|
||||
d.get(LF_FORM);
|
||||
lf.format("%sstd/lf0054.txt", __ptprf);
|
||||
if (fexist(lf) && fexist(d.filename()))
|
||||
f.load(lf);
|
||||
}
|
||||
}
|
||||
|
||||
void TConversione_archivi::convert_caus_attiv()
|
||||
@ -1934,55 +1928,213 @@ void TConversione_archivi::convert_pcon_ivd()
|
||||
prefix().set(pref);
|
||||
}
|
||||
|
||||
void TConversione_archivi::convert_profile(const char * profile_name)
|
||||
bool TConversione_archivi::backup_text_file(TFilename& name, TLog_report& log) const
|
||||
{
|
||||
TString msg;
|
||||
msg << TR("Elaborazione ") << name;
|
||||
log.log(0, "");
|
||||
log.log(0, msg);
|
||||
|
||||
if (!name.custom_path())
|
||||
{
|
||||
log.log_error(TR("Il file non esiste!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.find("custom") < 0)
|
||||
{
|
||||
log.log_error(TR("Il file non e' in una cartella custom!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
TFilename bakname(name);
|
||||
bakname << ".bak";
|
||||
if (!bakname.exist())
|
||||
{
|
||||
msg.cut(0) << TR("Copia ") << name << TR(" in ") << bakname;
|
||||
log.log(0, msg);
|
||||
fcopy(name, bakname);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TConversione_archivi::rinumera_paragrafo(const TFilename& ininame, const char*paragrafo,
|
||||
const char* contatore, const char* variabile,
|
||||
TLog_report& log) const
|
||||
{
|
||||
TConfig p(ininame, paragrafo);
|
||||
|
||||
TString val = p.get( contatore, paragrafo );
|
||||
if (val == "*")
|
||||
return true; // Lascia stare tutto!
|
||||
|
||||
const int ncols = atoi(val);
|
||||
const bool ok = p.remove(contatore) || ncols <= 0;
|
||||
if (!ok)
|
||||
{
|
||||
log.log(1, TR("Il file risulta essere gia' stato convertito"));
|
||||
return ok;
|
||||
}
|
||||
|
||||
TString4 str;
|
||||
for (int i = 1; i <= ncols; i++)
|
||||
{
|
||||
str.format("%d", i);
|
||||
val = p.get(str);
|
||||
p.remove(str);
|
||||
p.set(variabile, val, NULL, true, i - 1);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TConversione_archivi::rinumera_maschera(const TFilename& mskname, TLog_report& log) const
|
||||
{
|
||||
TFilename temp; temp.temp("msk");
|
||||
if (mskname.exist()) // Dummy test
|
||||
{
|
||||
TString msg;
|
||||
|
||||
TScanner scan(mskname);
|
||||
ofstream output(temp);
|
||||
|
||||
if (mskname.find("verig") > 0) // Maschera di riga
|
||||
{
|
||||
bool killing = false;
|
||||
while (!scan.eof())
|
||||
{
|
||||
TString& line = scan.line();
|
||||
if (!killing)
|
||||
{
|
||||
// Controllo per ammazzare i campi delle vecchie commesse 140,141,260,261
|
||||
if (line.match("?? 14[0,1] [1,2]0*") || line.match("?? 26[0,1] *"))
|
||||
{
|
||||
msg.cut(0) << TR("Eliminazione campo ") << line;
|
||||
log.log(1, msg);
|
||||
killing = true; // Comincio a saltar righe fino ad EN
|
||||
}
|
||||
else
|
||||
{
|
||||
// Controllo se devo rinumerare i vecchi CODAGG da 142,143 a 152,153
|
||||
if (line.match("?? 14[2,3] *")) // ST 142 12 -> ST 152 12
|
||||
{
|
||||
msg.cut(0) << TR("Rinumerazione campo ") << line;
|
||||
log.log(1, msg);
|
||||
line.overwrite("5", 4);
|
||||
} else
|
||||
if (line.match("IN * 14[2,3]")) // IN CODART 142 -> IN CODART 152
|
||||
{
|
||||
msg.cut(0) << TR("Rinumerazione campo ") << line;
|
||||
log.log(1, msg);
|
||||
line.overwrite("5", line.len()-2);
|
||||
}
|
||||
output << line << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finisco di ammazzare quando raggiungo il token EN
|
||||
if (line == "EN")
|
||||
killing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Maschera di testa
|
||||
{
|
||||
bool killing = false;
|
||||
while (!scan.eof())
|
||||
{
|
||||
TString& line = scan.line();
|
||||
if (!killing)
|
||||
{
|
||||
// Controllo per ammazzare i campi delle vecchie commesse 188,189,190,191
|
||||
if (line.match("?? 18[8,9] *") || line.match("?? 19[0,1] *"))
|
||||
{
|
||||
msg.cut(0) << TR("Eliminazione campo ") << line;
|
||||
log.log(1, msg);
|
||||
killing = true; // Comincio a saltar righe fino ad EN
|
||||
}
|
||||
else
|
||||
output << line << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finisco di ammazzare quando raggiungo il token EN
|
||||
if (line == "EN")
|
||||
killing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fcopy(temp, mskname);
|
||||
temp.fremove();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TConversione_archivi::convert_profile(const char* profile_name)
|
||||
{
|
||||
TConfig p(profile_name);
|
||||
TString16 str;
|
||||
int i;
|
||||
TArray_sheet elenco(-1, -1, -4, -4,
|
||||
TR("Profili da convertire"), TR("@1|Profilo@40|Maschera@40"));
|
||||
|
||||
int ncols = p.get_int( "NCOLS", "SHEET" );
|
||||
p.remove("NCOLS");
|
||||
for (i = 1; i <= ncols; i++)
|
||||
TFilename name = profile_name;
|
||||
name.ext("ini");
|
||||
if (name.custom_path()) // Esiste il profilo indicato?
|
||||
{
|
||||
str.format( "%d", i );
|
||||
const TString16 val(p.get(str));
|
||||
p.remove(str);
|
||||
p.set("Col", val, NULL, true, i - 1);
|
||||
TToken_string row;
|
||||
row = "X"; // preselezionato!
|
||||
row.add(name);
|
||||
name.ext("msk");
|
||||
if (name.exist()) // Esiste la maschera corrispondente?
|
||||
{
|
||||
row.add(name);
|
||||
elenco.add(row);
|
||||
}
|
||||
}
|
||||
|
||||
if (elenco.items() == 0) // Nessun nome valido specificato sulla riga di comando
|
||||
{
|
||||
name = prefix().get_studio();
|
||||
name.add("custom");
|
||||
name.add("*.ini");
|
||||
TString_array inis; list_files(name, inis);
|
||||
|
||||
FOR_EACH_ARRAY_ROW(inis, i, row)
|
||||
{
|
||||
TToken_string r;
|
||||
r = "X"; // preselezionato
|
||||
r.add(*row);
|
||||
name = *row; name.ext("msk");
|
||||
if (name.exist()) // Esiste la maschera corrispondente?
|
||||
{
|
||||
r.add(name);
|
||||
elenco.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int numtr = p.get_int( "NTIPIRIGA", "RIGHE" );
|
||||
p.remove( "NTIPIRIGA");
|
||||
|
||||
for (i = 1; i <= numtr; i ++ )
|
||||
if (elenco.run() == K_ENTER && elenco.one_checked())
|
||||
{
|
||||
str.format("%d", i);
|
||||
const TString16 tiporiga(p.get(str));
|
||||
p.remove(str);
|
||||
p.set("Tipo", tiporiga, NULL, true, i - 1);
|
||||
}
|
||||
TLog_report log(TR("Conversione maschere documenti"));
|
||||
|
||||
const int hitems = p.get_int("NHANDLER", "HANDLERS");
|
||||
p.remove("NHANDLER");
|
||||
for (int r = 0; r < elenco.items(); r++) if (elenco.checked(r))
|
||||
{
|
||||
name = elenco.row(r).get(1);
|
||||
if (!backup_text_file(name, log))
|
||||
continue;
|
||||
const bool ok = rinumera_paragrafo(name, "SHEET", "NCOLS", "Col", log);
|
||||
if (!ok)
|
||||
continue; // Gia' elaborato!
|
||||
rinumera_paragrafo(name, "RIGHE", "NTIPIRIGA", "Tipo", log);
|
||||
rinumera_paragrafo(name, "HANDLERS", "NHANDLER", "Handler", log);
|
||||
rinumera_paragrafo(name, "DEFAULT", "NDEFAULTS", "Default", log);
|
||||
|
||||
for (i = 1; i <= hitems; i++)
|
||||
{
|
||||
str.format("%d", i);
|
||||
const TToken_string h(p.get(str));
|
||||
name = elenco.row(r).get(2);
|
||||
if (backup_text_file(name, log))
|
||||
rinumera_maschera(name, log);
|
||||
}
|
||||
|
||||
p.remove(str);
|
||||
p.set("Handler", h, NULL, true, i - 1);
|
||||
}
|
||||
|
||||
const int ditems = p.get_int("NDEFAULTS", "DEFAULT");
|
||||
p.remove("NDEFAULTS");
|
||||
|
||||
for (i = 1; i <= ditems; i++)
|
||||
{
|
||||
str.format("%d", i);
|
||||
const TToken_string h(p.get(str));
|
||||
|
||||
p.remove(str);
|
||||
p.set("Default", h, NULL, true, i - 1);
|
||||
log.preview();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2003,12 +2155,12 @@ int main(int argc,char** argv)
|
||||
if (r==0)
|
||||
{
|
||||
TConversione_xbase a;
|
||||
a.run(argc,argv, "Conversione archivi di xBase");
|
||||
a.run(argc,argv, TR("Conversione archivi di xBase"));
|
||||
}
|
||||
else
|
||||
{
|
||||
TConversione_archivi a ;
|
||||
a.run(argc, argv, "Conversione archivi");
|
||||
a.run(argc, argv, TR("Conversione archivi"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user