Merge branch 'R_10_00' of http://10.65.20.33/sirio/CAMPO/campo into R_10_00
This commit is contained in:
commit
5658145334
@ -253,6 +253,18 @@
|
||||
<ItemGroup>
|
||||
<MenCompiler Include="..\src\fp\fpmenu.men" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TrrCompiler Include="..\src\fp\f176.trr" />
|
||||
<TrrCompiler Include="..\src\fp\f177.trr" />
|
||||
<TrrCompiler Include="..\src\fp\f178.trr" />
|
||||
<TrrCompiler Include="..\src\fp\f179.trr" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<DirCompiler Include="..\src\fp\f176.dir" />
|
||||
<DirCompiler Include="..\src\fp\f177.dir" />
|
||||
<DirCompiler Include="..\src\fp\f178.dir" />
|
||||
<DirCompiler Include="..\src\fp\f179.dir" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="CampoRules.targets" />
|
||||
|
@ -22,6 +22,12 @@
|
||||
<Filter Include="Sources">
|
||||
<UniqueIdentifier>{06bc8aeb-f506-4c2e-85fb-bdeb92f2c77e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Trr">
|
||||
<UniqueIdentifier>{f86bc7e9-c06f-4646-a713-f6a10ee12e00}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Dir">
|
||||
<UniqueIdentifier>{26bb518e-9e58-4988-9634-c5ce9b2573af}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\fp\fp0.cpp">
|
||||
@ -125,4 +131,32 @@
|
||||
<Filter>Menu</Filter>
|
||||
</MenCompiler>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TrrCompiler Include="..\src\fp\f176.trr">
|
||||
<Filter>Trr</Filter>
|
||||
</TrrCompiler>
|
||||
<TrrCompiler Include="..\src\fp\f177.trr">
|
||||
<Filter>Trr</Filter>
|
||||
</TrrCompiler>
|
||||
<TrrCompiler Include="..\src\fp\f178.trr">
|
||||
<Filter>Trr</Filter>
|
||||
</TrrCompiler>
|
||||
<TrrCompiler Include="..\src\fp\f179.trr">
|
||||
<Filter>Trr</Filter>
|
||||
</TrrCompiler>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<DirCompiler Include="..\src\fp\f176.dir">
|
||||
<Filter>Dir</Filter>
|
||||
</DirCompiler>
|
||||
<DirCompiler Include="..\src\fp\f177.dir">
|
||||
<Filter>Dir</Filter>
|
||||
</DirCompiler>
|
||||
<DirCompiler Include="..\src\fp\f178.dir">
|
||||
<Filter>Dir</Filter>
|
||||
</DirCompiler>
|
||||
<DirCompiler Include="..\src\fp\f179.dir">
|
||||
<Filter>Dir</Filter>
|
||||
</DirCompiler>
|
||||
</ItemGroup>
|
||||
</Project>
|
3
cd/test/mr0822.txt
Normal file
3
cd/test/mr0822.txt
Normal file
@ -0,0 +1,3 @@
|
||||
mr0.exe
|
||||
|
||||
Aggiunta ora e minuti al salvataggio del file di rilevazione dei terminalini per aumentare la precisione
|
23
cd/test/mr0822a.ini
Normal file
23
cd/test/mr0822a.ini
Normal file
@ -0,0 +1,23 @@
|
||||
[Main]
|
||||
Demo=0
|
||||
|
||||
[mr1]
|
||||
Edit_4 = mr0 -1
|
||||
Edit_5 = mr0 -1
|
||||
File(1) = mr0.exe|X
|
||||
Patch = 822
|
||||
Versione = 21511200
|
||||
|
||||
[mr]
|
||||
Data = 12-06-2019
|
||||
Descrizione = Manufacturing Resource Planning
|
||||
Dischi = 1
|
||||
Moduli = mg,db,ve
|
||||
OEM =
|
||||
Patch = 822
|
||||
PostProcess =
|
||||
PreProcess =
|
||||
Prezzo(1) =
|
||||
Prezzo(2) =
|
||||
Versione = 21511200
|
||||
|
BIN
cd/test/mr0822a1.zip
Normal file
BIN
cd/test/mr0822a1.zip
Normal file
Binary file not shown.
3
cd/test/tp0822.txt
Normal file
3
cd/test/tp0822.txt
Normal file
@ -0,0 +1,3 @@
|
||||
tp0.exe
|
||||
|
||||
Aggiunto messaggio con codice dell'articolo avente conai errato durante l'importazione
|
21
cd/test/tp0822a.ini
Normal file
21
cd/test/tp0822a.ini
Normal file
@ -0,0 +1,21 @@
|
||||
[Main]
|
||||
Demo=0
|
||||
|
||||
[tp1]
|
||||
File(0) = tp0.exe|X
|
||||
Patch = 0822
|
||||
Versione = 21511200
|
||||
|
||||
[tp]
|
||||
Data = 12-06-2019
|
||||
Descrizione = Trasferimento PACK
|
||||
Dischi = 1
|
||||
Moduli = ve
|
||||
OEM =
|
||||
Patch = 822
|
||||
PostProcess =
|
||||
PreProcess =
|
||||
Prezzo(1) =
|
||||
Prezzo(2) =
|
||||
Versione = 21511200
|
||||
|
BIN
cd/test/tp0822a1.zip
Normal file
BIN
cd/test/tp0822a1.zip
Normal file
Binary file not shown.
5
cd/test/ve0820.txt
Normal file
5
cd/test/ve0820.txt
Normal file
@ -0,0 +1,5 @@
|
||||
ve5.exe
|
||||
ve5100a.msk
|
||||
|
||||
Scarico e ripristino documenti:
|
||||
Aggiunta archiviazione su File oltre al Floppy
|
130
cd/test/ve0820a.ini
Normal file
130
cd/test/ve0820a.ini
Normal file
@ -0,0 +1,130 @@
|
||||
[Main]
|
||||
Demo=0
|
||||
|
||||
[ve1]
|
||||
File(86) = ve5.exe|X
|
||||
File(87) = ve5100a.msk|X
|
||||
Patch = 0820
|
||||
Versione = 21511200
|
||||
|
||||
[ve99]
|
||||
Kill(0) = batbcld.msk|x
|
||||
Kill(1) = bastspp.rep|x
|
||||
Kill(2) = baststd.rep|x
|
||||
Kill(3) = bastbnp.rep|x
|
||||
Kill(4) = ve7400a.msk|x
|
||||
Kill(5) = bastfrd.msk|x
|
||||
Kill(6) = bastprs.rep|x
|
||||
Kill(7) = basttip.msk|x
|
||||
Kill(8) = bastcaa.rep|x
|
||||
Kill(9) = efstbnp.msk|x
|
||||
Kill(10) = batbprs.msk|x
|
||||
Kill(11) = batbabe.msk|x
|
||||
Kill(12) = bastgca.msk|x
|
||||
Kill(13) = batbgmc.msk|x
|
||||
Kill(14) = bastcau.rep|x
|
||||
Kill(15) = bastcra.msk|x
|
||||
Kill(16) = bastspp.msk|x
|
||||
Kill(17) = basttag.rep|x
|
||||
Kill(18) = batbcau.msk|x
|
||||
Kill(19) = bastctr.rep|x
|
||||
Kill(20) = ve7500a.msk|x
|
||||
Kill(21) = bastasf.rep|x
|
||||
Kill(22) = bastums.rep|x
|
||||
Kill(23) = bastfrr.msk|x
|
||||
Kill(24) = basteld.rep|x
|
||||
Kill(25) = batbprv.msk|x
|
||||
Kill(26) = ve7200a.msk|x
|
||||
Kill(27) = batbgca.msk|x
|
||||
Kill(28) = batbmre.msk|x
|
||||
Kill(29) = bastcaa.msk|x
|
||||
Kill(30) = ve7700a.msk|x
|
||||
Kill(31) = batbtri.msk|x
|
||||
Kill(32) = basttip.rep|x
|
||||
Kill(33) = efstbnp.rep|x
|
||||
Kill(34) = baststd.msk|x
|
||||
Kill(35) = batbasf.msk|x
|
||||
Kill(36) = bastimb.msk|x
|
||||
Kill(37) = batbrfa.msk|x
|
||||
Kill(38) = ve7300a.msk|x
|
||||
Kill(39) = ve7600a.msk|x
|
||||
Kill(40) = batbspt.msk|x
|
||||
Kill(41) = bastfca.rep|x
|
||||
Kill(42) = bastrfc.msk|x
|
||||
Kill(43) = bastprs.msk|x
|
||||
Kill(44) = bastgcg.msk|x
|
||||
Kill(45) = batbspp.msk|x
|
||||
Kill(46) = batbgcg.msk|x
|
||||
Kill(47) = bastnum.rep|x
|
||||
Kill(48) = bastgmc.msk|x
|
||||
Kill(49) = batbrfc.msk|x
|
||||
Kill(50) = bastubi.msk|x
|
||||
Kill(51) = batbtag.msk|x
|
||||
Kill(52) = ve7400a.ini|x
|
||||
Kill(53) = bastrfa.msk|x
|
||||
Kill(54) = bastabe.rep|x
|
||||
Kill(55) = bastubi.rep|x
|
||||
Kill(56) = bastasf.msk|x
|
||||
Kill(57) = batbctr.msk|x
|
||||
Kill(58) = ve7100a.msk|x
|
||||
Kill(59) = batbcaa.msk|x
|
||||
Kill(60) = batbfid.msk|x
|
||||
Kill(61) = ve7300a.frm|x
|
||||
Kill(62) = bastfrr.rep|x
|
||||
Kill(63) = bastums.msk|x
|
||||
Kill(64) = basttri.rep|x
|
||||
Kill(65) = bastrfa.rep|x
|
||||
Kill(66) = bastcau.msk|x
|
||||
Kill(67) = batbtip.msk|x
|
||||
Kill(68) = batbubi.msk|x
|
||||
Kill(69) = basttag.msk|x
|
||||
Kill(70) = basteld.msk|x
|
||||
Kill(71) = bastimb.rep|x
|
||||
Kill(72) = bastrfc.rep|x
|
||||
Kill(73) = ve7.exe|x
|
||||
Kill(74) = ve7200a.frm|x
|
||||
Kill(75) = batbfrr.msk|x
|
||||
Kill(76) = bastfca.msk|x
|
||||
Kill(77) = batbfrd.msk|x
|
||||
Kill(78) = bastctr.msk|x
|
||||
Kill(79) = batbpro.msk|x
|
||||
Kill(80) = ve7400conf.ini|x
|
||||
Kill(81) = bastfrm.rep|x
|
||||
Kill(82) = batbbnp.msk|x
|
||||
Kill(83) = bastgca.rep|x
|
||||
Kill(84) = batbstd.msk|x
|
||||
Kill(85) = ve7701a.ini|x
|
||||
Kill(86) = batbfsa.msk|x
|
||||
Kill(87) = batbnum.msk|x
|
||||
Kill(88) = bastabe.msk|x
|
||||
Kill(89) = eftbbnp.msk|x
|
||||
Kill(90) = batbfca.msk|x
|
||||
Kill(91) = bastgcg.rep|x
|
||||
Kill(92) = batbgsa.msk|x
|
||||
Kill(93) = bastfrm.msk|x
|
||||
Kill(94) = bastbnp.msk|x
|
||||
Kill(95) = bastgmc.rep|x
|
||||
Kill(96) = bastcra.rep|x
|
||||
Kill(97) = bastfrd.rep|x
|
||||
Kill(98) = batbacr.msk|x
|
||||
Kill(99) = batbimb.msk|x
|
||||
Kill(100) = basttri.msk|x
|
||||
Kill(101) = bastnum.msk|x
|
||||
Kill(102) = batbeld.msk|x
|
||||
Kill(103) = batbums.msk|x
|
||||
Kill(104) = batbcra.msk|x
|
||||
Kill(105) = batbfrm.msk|x
|
||||
|
||||
[ve]
|
||||
Data = 11-06-2019
|
||||
Descrizione = Vendite
|
||||
Dischi = 1
|
||||
Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9
|
||||
OEM =
|
||||
Patch = 820
|
||||
PostProcess = bainst -0 VE
|
||||
PreProcess =
|
||||
Prezzo(1) =
|
||||
Prezzo(2) =
|
||||
Versione = 21511200
|
||||
|
BIN
cd/test/ve0820a1.zip
Normal file
BIN
cd/test/ve0820a1.zip
Normal file
Binary file not shown.
3
src/fp/f176.dir
Normal file
3
src/fp/f176.dir
Normal file
@ -0,0 +1,3 @@
|
||||
176
|
||||
0
|
||||
$fpcust|2|2|62|0|Personalizzazioni FP|||
|
7
src/fp/f176.trr
Normal file
7
src/fp/f176.trr
Normal file
@ -0,0 +1,7 @@
|
||||
176
|
||||
3
|
||||
CODICE|1|10|0|
|
||||
DESCR|1|50|0|
|
||||
GLOBAL|8|1|0|
|
||||
1
|
||||
CODICE|
|
3
src/fp/f177.dir
Normal file
3
src/fp/f177.dir
Normal file
@ -0,0 +1,3 @@
|
||||
177
|
||||
0
|
||||
$fpccaus|1|1|465|0|Personalizzazioni causale FP|||
|
8
src/fp/f177.trr
Normal file
8
src/fp/f177.trr
Normal file
@ -0,0 +1,8 @@
|
||||
177
|
||||
4
|
||||
CODICE|1|10|0|
|
||||
NRIGA|2|4|0|
|
||||
VALORE|1|250|0|
|
||||
COND|1|200|0|
|
||||
1
|
||||
CODICE+NRIGA|
|
3
src/fp/f178.dir
Normal file
3
src/fp/f178.dir
Normal file
@ -0,0 +1,3 @@
|
||||
178
|
||||
0
|
||||
$fpcart|0|0|613|0|Personalizzazioni articoli FP|||
|
9
src/fp/f178.trr
Normal file
9
src/fp/f178.trr
Normal file
@ -0,0 +1,9 @@
|
||||
178
|
||||
5
|
||||
CODICE|1|10|0|
|
||||
NRIGA|2|2|0|
|
||||
TIPO|1|200|0|
|
||||
VALORE|1|200|0|
|
||||
COND|1|200|0|
|
||||
1
|
||||
CODICE+NRIGA|
|
3
src/fp/f179.dir
Normal file
3
src/fp/f179.dir
Normal file
@ -0,0 +1,3 @@
|
||||
179
|
||||
0
|
||||
$fpcadg|0|0|1017|0|Personalizzazioni AltriDatiGestionali FP|||
|
13
src/fp/f179.trr
Normal file
13
src/fp/f179.trr
Normal file
@ -0,0 +1,13 @@
|
||||
179
|
||||
9
|
||||
CODICE|1|10|0|
|
||||
NRIGA|2|3|0|
|
||||
TIPODATO|1|200|0|
|
||||
RTESTO|1|200|0|
|
||||
RNUMERO|1|200|0|
|
||||
RDATA|1|200|0|
|
||||
TIPORIGA|1|2|0|
|
||||
SPLIT|8|1|0|
|
||||
COND|1|200|0|
|
||||
1
|
||||
CODICE+NRIGA|
|
@ -175,7 +175,7 @@ BEGIN
|
||||
DISPLAY "Tipo riga@8" CODTAB
|
||||
DISPLAY "Descrizione@50" S0
|
||||
OUTPUT S_ADG_TIPORIGA CODTAB
|
||||
HELP "Condizione che se è vera abilita la riga"
|
||||
HELP "La personalizzazione viene abilitata solo su queste righe"
|
||||
END
|
||||
|
||||
STRING S_ADG_COND 200 50
|
||||
|
@ -269,8 +269,6 @@ protected:
|
||||
bool export_paf0100f();
|
||||
bool export_paf3200f();
|
||||
|
||||
|
||||
|
||||
// Record clifo
|
||||
//void set_rec_clifo(char tipocf, long codcf);
|
||||
|
||||
@ -287,14 +285,6 @@ public:
|
||||
int force_commit();
|
||||
void set_cache_insert(const bool v) { _cache_insert = v; }
|
||||
|
||||
// Test
|
||||
static const TString& parse_expression(const TString& expr, TRiga_documento& rdoc);
|
||||
static TString& parse_read(const TString& str, TRiga_documento& rdoc);
|
||||
static TString& do_read(const TString& tabella, const TString& campo, TRiga_documento& rdoc);
|
||||
static TString& parse_search(const TString& str, TRiga_documento& rdoc);
|
||||
|
||||
|
||||
|
||||
TDoc_fp();
|
||||
~TDoc_fp();
|
||||
};
|
||||
@ -490,4 +480,29 @@ public:
|
||||
for (int __r = bodyof##__radg.first_row(); bodyof##__radg.exist(__r) && (__radg=&(TRectype&)bodyof##__radg.row(__r))!=NULL; __r=bodyof##__radg.succ_row(__r))
|
||||
|
||||
|
||||
class TFP_expression : public TObject
|
||||
{
|
||||
private:
|
||||
enum TFP_operator { error, eq, neq, gt, ls, gteq, lseq };
|
||||
|
||||
// Etrattori
|
||||
static void extract_info(const TString& expr, TString& tabella, TString& campo, TToken_string* search);
|
||||
static bool calc_table(const TString& tabella, int& file);
|
||||
static void split_condition(const TString& cond, TString& cond_sx, TString& cond_dx, TFP_operator& symb);
|
||||
static TVariant& get_value(const TRectype& rec, const TString& campo);
|
||||
static TVariant& parse_var(const TString& str);
|
||||
|
||||
// Calcolatori
|
||||
static TVariant& parse_read(const TString& str, TRiga_documento& rdoc);
|
||||
static TVariant& do_read(const TString& tabella, const TString& campo, TRiga_documento& rdoc);
|
||||
static TVariant& parse_search(const TString& str, TRiga_documento& rdoc);
|
||||
|
||||
public:
|
||||
static const TVariant parse_expression(const TString& expr, TRiga_documento& rdoc);
|
||||
static bool check_condition(const TString& cond, TRiga_documento& rdoc);
|
||||
|
||||
TFP_expression() = default;
|
||||
virtual ~TFP_expression() = default;
|
||||
};
|
||||
|
||||
#endif // __FPLIB_H
|
||||
|
@ -1408,164 +1408,6 @@ bool TDoc_fp::export_paf3200f()
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sintassi:
|
||||
* READ(TABELLA, CAMPO) -> legge dalle tabelle predefinite
|
||||
* SEARCH(TABELLA, CAMPO, RICERCA) -> legge da una tabella qualsiasi
|
||||
* SEARCH e READ sono diverse sotto richiesta di Ilaria per avere una sintassi più chiara
|
||||
* resto: TExpr_documento()
|
||||
*/
|
||||
const TString& TDoc_fp::parse_expression(const TString& expr, TRiga_documento& rdoc)
|
||||
{
|
||||
const TToken_string exprs(expr, '+');
|
||||
TString& result = get_tmp_string().cut(0);
|
||||
TExpr_documento expr_documento(_mixexpr, &rdoc.doc(), &rdoc);
|
||||
|
||||
FOR_EACH_STR_TOKEN(exprs, str)
|
||||
{
|
||||
// Come prima cosa trimmo la vita
|
||||
str.trim();
|
||||
if(str.starts_with("READ(", true))
|
||||
{
|
||||
result << parse_read(str, rdoc);
|
||||
} else if(str.starts_with("SEARCH(", true))
|
||||
{
|
||||
result << parse_search(str, rdoc);
|
||||
} else
|
||||
{
|
||||
// Controllo non sia una ricerca a DB con il punto
|
||||
if(expr.contains("->"))
|
||||
{
|
||||
// Se contiene una freccia non posso fare un TToken_string easy
|
||||
// Non esistono campi con -> vero?
|
||||
str.replace("->", ".");
|
||||
}
|
||||
|
||||
// Questo diventa true se sono passato sopra o effettivamente ha un punto dall'inizio
|
||||
if(expr.contains('.'))
|
||||
{
|
||||
TToken_string simple_field(expr, '.');
|
||||
result << do_read(simple_field.get(0), simple_field.get(), rdoc);
|
||||
}
|
||||
// Se inizia come una stringa o non contiene parentesi -> no expr
|
||||
else if (str.starts_with("\"") || !(str.contains("(") && str.contains(")")))
|
||||
{
|
||||
str.replace("\"", "");
|
||||
result << str;
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_documento.set(str, _mixexpr);
|
||||
result << expr_documento.as_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void extract_info(const TString& expr, TString& tabella, TString& campo, TToken_string* search)
|
||||
{
|
||||
// Prendo la stringa pulita della parte sinistra
|
||||
TString clean_expr = expr.mid(expr.find('(') + 1);
|
||||
// Tolgo eventuali spazi ai lati
|
||||
clean_expr.trim();
|
||||
// Tolgo la virgola finale
|
||||
clean_expr.rtrim(1);
|
||||
TToken_string info(clean_expr, ',');
|
||||
|
||||
// Trimmare sempre come se non sapessi fare altro nella vita
|
||||
tabella.cut(0) << info.remove(0); tabella.trim();
|
||||
campo.cut(0) << info.remove(0); campo.trim();
|
||||
if(search != nullptr)
|
||||
{
|
||||
// Prendo il resto
|
||||
search->cut(0) << info;
|
||||
search->trim();
|
||||
search->restart();
|
||||
}
|
||||
}
|
||||
|
||||
bool calc_table(const TString& tabella, int& file)
|
||||
{
|
||||
file = atoi(tabella);
|
||||
if (file == 0)
|
||||
file = table2logic(tabella);
|
||||
return is_multi_table(file);
|
||||
}
|
||||
|
||||
TString& TDoc_fp::parse_read(const TString& str, TRiga_documento& rdoc)
|
||||
{
|
||||
TString tabella, campo;
|
||||
|
||||
extract_info(str, tabella, campo, nullptr);
|
||||
|
||||
return do_read(tabella, campo, rdoc);
|
||||
}
|
||||
|
||||
TString& TDoc_fp::do_read(const TString& tabella, const TString& campo, TRiga_documento& rdoc)
|
||||
{
|
||||
TString& result = get_tmp_string().cut(0);
|
||||
int file;
|
||||
|
||||
bool multi_table = calc_table(tabella, file);
|
||||
|
||||
switch (file)
|
||||
{
|
||||
case LF_DOC:
|
||||
result = rdoc.doc().get(campo);
|
||||
break;
|
||||
case LF_RIGHEDOC:
|
||||
result = rdoc.get(campo);
|
||||
break;
|
||||
case LF_CLIFO:
|
||||
result = rdoc.doc().clifor().get(campo);
|
||||
break;
|
||||
case LF_CFVEN:
|
||||
result = rdoc.doc().clifor().vendite().get(campo);
|
||||
break;
|
||||
case LF_LETINT:
|
||||
result = rdoc.doc().clifor().lettera().get(campo);
|
||||
break;
|
||||
case LF_ANAMAG:
|
||||
result = rdoc.articolo().get(campo);
|
||||
break;
|
||||
default:
|
||||
// Skip
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TString& TDoc_fp::parse_search(const TString& str, TRiga_documento& rdoc)
|
||||
{
|
||||
TString& result = get_tmp_string();
|
||||
|
||||
TString tabella, campo;
|
||||
TToken_string input_search, search;
|
||||
int file;
|
||||
|
||||
extract_info(str, tabella, campo, &input_search);
|
||||
const bool multi_table = calc_table(tabella, file);
|
||||
|
||||
// Parso ogni singolo token della ricerca
|
||||
FOR_EACH_TOKEN(input_search, tok)
|
||||
{
|
||||
search.add(parse_expression(tok, rdoc));
|
||||
}
|
||||
|
||||
if(multi_table)
|
||||
{
|
||||
result.cut(0) << cache().get(tabella, search, campo);
|
||||
} else
|
||||
{
|
||||
result.cut(0) << cache().get(file, search, campo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc)
|
||||
{
|
||||
if (!initialize(doc))
|
||||
|
@ -37,6 +37,7 @@ void TFP_custom::autoload(const TSheet_field& sf, const int file) const
|
||||
{
|
||||
TRectype& rec_row = rcaus.row(-1, true);
|
||||
rec_row.put(FPCCAUS_VALORE, row->get(0));
|
||||
rec_row.put(FPCCAUS_COND, row->get());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -49,6 +50,7 @@ void TFP_custom::autoload(const TSheet_field& sf, const int file) const
|
||||
TRectype& rec_row = rart.row(-1, true);
|
||||
rec_row.put(FPCART_TIPO, row->get(0));
|
||||
rec_row.put(FPCART_VALORE, row->get());
|
||||
rec_row.put(FPCART_COND, row->get());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -63,6 +65,9 @@ void TFP_custom::autoload(const TSheet_field& sf, const int file) const
|
||||
rec_row.put(FPCADG_RTESTO, row->get());
|
||||
rec_row.put(FPCADG_RNUMERO, row->get());
|
||||
rec_row.put(FPCADG_RDATA, row->get());
|
||||
rec_row.put(FPCADG_TIPORIGA, row->get());
|
||||
rec_row.put(FPCADG_SPLIT, row->get());
|
||||
rec_row.put(FPCADG_COND, row->get());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -89,3 +94,315 @@ TFP_custom::TFP_custom(const char* codcust) : TFP_custom()
|
||||
init();
|
||||
load(codcust);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Sintassi:
|
||||
* READ(TABELLA, CAMPO) -> legge dalle tabelle predefinite
|
||||
* SEARCH(TABELLA, CAMPO, RICERCA) -> legge da una tabella qualsiasi
|
||||
* SEARCH e READ sono diverse sotto richiesta di Ilaria per avere una sintassi più chiara
|
||||
* resto: TExpr_documento()
|
||||
*/
|
||||
const TVariant TFP_expression::parse_expression(const TString& expr, TRiga_documento& rdoc)
|
||||
{
|
||||
const TToken_string exprs(expr, '+');
|
||||
TVariant result;
|
||||
TExpr_documento expr_documento(_mixexpr, &rdoc.doc(), &rdoc);
|
||||
|
||||
FOR_EACH_STR_TOKEN(exprs, str)
|
||||
{
|
||||
// Come prima cosa trimmo la vita
|
||||
str.trim();
|
||||
if (str.starts_with("READ(", true))
|
||||
{
|
||||
result.add(parse_read(str, rdoc));
|
||||
}
|
||||
else if (str.starts_with("SEARCH(", true))
|
||||
{
|
||||
result.add(parse_search(str, rdoc));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Controllo non sia una ricerca a DB con il punto
|
||||
if (expr.contains("->"))
|
||||
{
|
||||
// Se contiene una freccia non posso fare un TToken_string easy
|
||||
// Non esistono campi con -> vero?
|
||||
str.replace("->", ".");
|
||||
}
|
||||
|
||||
// Questo diventa true se sono passato sopra o effettivamente ha un punto dall'inizio
|
||||
if (expr.contains('.'))
|
||||
{
|
||||
TToken_string simple_field(expr, '.');
|
||||
result.add(do_read(simple_field.get(0), simple_field.get(), rdoc));
|
||||
}
|
||||
// Se inizia come una stringa o non contiene parentesi -> no expr
|
||||
else if (str.starts_with("\"") || !(str.contains("(") && str.contains(")")))
|
||||
{
|
||||
str.replace("\"", "");
|
||||
// Cerchiamo di capire che è
|
||||
result.add(parse_var(str));
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_documento.set(str, _mixexpr);
|
||||
result.add(expr_documento.as_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TFP_expression::check_condition(const TString& cond, TRiga_documento& rdoc)
|
||||
{
|
||||
TString cond_sx, cond_dx;
|
||||
TFP_operator symb;
|
||||
split_condition(cond, cond_sx, cond_dx, symb);
|
||||
|
||||
const TVariant value_sx = parse_expression(cond_sx, rdoc);
|
||||
const TVariant value_dx = parse_expression(cond_dx, rdoc);
|
||||
|
||||
switch(symb)
|
||||
{
|
||||
case eq:
|
||||
return value_sx == value_dx;
|
||||
case neq:
|
||||
return value_sx != value_dx;
|
||||
case gt:
|
||||
return value_sx > value_dx;
|
||||
case ls:
|
||||
return value_sx < value_dx;
|
||||
case gteq:
|
||||
return value_sx >= value_dx;
|
||||
case lseq:
|
||||
return value_sx <= value_dx;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void TFP_expression::extract_info(const TString& expr, TString& tabella, TString& campo, TToken_string* search)
|
||||
{
|
||||
// Prendo la stringa pulita della parte sinistra
|
||||
TString clean_expr = expr.mid(expr.find('(') + 1);
|
||||
// Tolgo eventuali spazi ai lati
|
||||
clean_expr.trim();
|
||||
// Tolgo la virgola finale
|
||||
clean_expr.rtrim(1);
|
||||
TToken_string info(clean_expr, ',');
|
||||
|
||||
// Trimmare sempre come se non sapessi fare altro nella vita
|
||||
tabella.cut(0) << info.remove(0); tabella.trim();
|
||||
campo.cut(0) << info.remove(0); campo.trim();
|
||||
if (search != nullptr)
|
||||
{
|
||||
// Prendo il resto
|
||||
search->cut(0) << info;
|
||||
search->trim();
|
||||
search->restart();
|
||||
}
|
||||
}
|
||||
|
||||
bool TFP_expression::calc_table(const TString& tabella, int& file)
|
||||
{
|
||||
file = atoi(tabella);
|
||||
if (file == 0)
|
||||
file = table2logic(tabella);
|
||||
return is_multi_table(file);
|
||||
}
|
||||
|
||||
void TFP_expression::split_condition(const TString& cond, TString& cond_sx, TString& cond_dx, TFP_operator& symb)
|
||||
{
|
||||
// Cerchiamo di capire che condizione ho
|
||||
TString4 symbol;
|
||||
if(cond.contains(" == "))
|
||||
{
|
||||
symb = eq;
|
||||
symbol = " == ";
|
||||
}
|
||||
else if(cond.contains(" != "))
|
||||
{
|
||||
symb = neq;
|
||||
symbol = " != ";
|
||||
}
|
||||
else if (cond.contains(" >= "))
|
||||
{
|
||||
symb = gteq;
|
||||
symbol = " >= ";
|
||||
}
|
||||
else if (cond.contains(" <= "))
|
||||
{
|
||||
symb = lseq;
|
||||
symbol = " <= ";
|
||||
}
|
||||
else if (cond.contains(" > "))
|
||||
{
|
||||
symb = gt;
|
||||
symbol = " > ";
|
||||
}
|
||||
else if (cond.contains(" < "))
|
||||
{
|
||||
symb = ls;
|
||||
symbol = " < ";
|
||||
}
|
||||
|
||||
if(symb != error)
|
||||
{
|
||||
cond_sx = cond.left(cond.find(symbol));
|
||||
cond_dx = cond.right(cond.len() - (cond.find(symbol) + symbol.len()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Considero come se è true o no il campo in generale
|
||||
symb = gt;
|
||||
cond_sx = cond;
|
||||
cond_dx.cut(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Questa funzione potrebbe diventare standard per TRectype
|
||||
TVariant& TFP_expression::get_value(const TRectype& rec, const TString& campo)
|
||||
{
|
||||
TVariant& ret = get_tmp_var();
|
||||
switch(rec.type(campo))
|
||||
{
|
||||
case _intfld:
|
||||
ret.set(rec.get_int(campo));
|
||||
break;
|
||||
case _longfld:
|
||||
ret.set(rec.get_long(campo));
|
||||
break;
|
||||
case _realfld:
|
||||
ret.set(rec.get_real(campo));
|
||||
break;
|
||||
case _datefld:
|
||||
ret.set(rec.get_date(campo));
|
||||
break;
|
||||
case _wordfld:
|
||||
ret.set(rec.get_word(campo));
|
||||
break;
|
||||
case _charfld:
|
||||
ret.set(rec.get_char(campo));
|
||||
break;
|
||||
case _boolfld:
|
||||
ret.set(rec.get_bool(campo));
|
||||
break;
|
||||
case _nullfld:
|
||||
case _alfafld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
case _memofld:
|
||||
ret.set(rec.get(campo));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
TVariant& TFP_expression::parse_var(const TString& str)
|
||||
{
|
||||
TVariant& ret = get_tmp_var();
|
||||
|
||||
// Come prima cosa leggo la stringa e cerco di capire se ci sono numeri o no
|
||||
bool is_real = false, is_string = false;
|
||||
for(int i = 0; i < str.len() && !is_string; i++)
|
||||
{
|
||||
const char val = str[i];
|
||||
if(val < '0' || val > '9')
|
||||
{
|
||||
if (val == '.' || val == ',')
|
||||
is_real = true;
|
||||
else
|
||||
is_string = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Una volta che ho capito che ho davanti tento il trick!
|
||||
if (is_string)
|
||||
{
|
||||
// Tento la data
|
||||
const TDate pop(str);
|
||||
|
||||
if (pop.ok())
|
||||
ret.add(pop);
|
||||
else
|
||||
ret.add(str);
|
||||
}
|
||||
else if (is_real)
|
||||
ret.add(real(str));
|
||||
else
|
||||
{
|
||||
char* err;
|
||||
const long long_val = strtol(str, &err, 10);
|
||||
// Ho avuto un errore? Il controllo ha fallito!
|
||||
if(err && *err)
|
||||
{
|
||||
ret.add(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.add(long_val);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TVariant& TFP_expression::parse_read(const TString& str, TRiga_documento& rdoc)
|
||||
{
|
||||
TString tabella, campo;
|
||||
extract_info(str, tabella, campo, nullptr);
|
||||
return do_read(tabella, campo, rdoc);
|
||||
}
|
||||
|
||||
TVariant& TFP_expression::do_read(const TString& tabella, const TString& campo, TRiga_documento& rdoc)
|
||||
{
|
||||
int file;
|
||||
calc_table(tabella, file);
|
||||
|
||||
switch (file)
|
||||
{
|
||||
case LF_DOC:
|
||||
return get_value(rdoc.doc(), campo);
|
||||
case LF_RIGHEDOC:
|
||||
return get_value(rdoc, campo);
|
||||
case LF_CLIFO:
|
||||
return get_value(rdoc.doc().clifor(), campo);
|
||||
case LF_CFVEN:
|
||||
return get_value(rdoc.doc().clifor().vendite(), campo);
|
||||
case LF_LETINT:
|
||||
return get_value(rdoc.doc().clifor().lettera(), campo);
|
||||
case LF_ANAMAG:
|
||||
return get_value(rdoc.articolo(), campo);
|
||||
default:
|
||||
static TVariant null_var(EMPTY_STRING);
|
||||
return null_var;
|
||||
}
|
||||
}
|
||||
|
||||
TVariant& TFP_expression::parse_search(const TString& str, TRiga_documento& rdoc)
|
||||
{
|
||||
TString tabella, campo;
|
||||
TToken_string input_search, search;
|
||||
int file;
|
||||
|
||||
extract_info(str, tabella, campo, &input_search);
|
||||
const bool multi_table = calc_table(tabella, file);
|
||||
|
||||
// Parso ogni singolo token della ricerca
|
||||
FOR_EACH_TOKEN(input_search, tok)
|
||||
{
|
||||
search.add(parse_expression(tok, rdoc).as_string());
|
||||
}
|
||||
|
||||
if (multi_table)
|
||||
{
|
||||
return get_value(cache().get(tabella, search), campo);
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_value(cache().get(file, search), campo);
|
||||
}
|
||||
}
|
||||
|
@ -494,6 +494,7 @@ int TRecordset::find_column(const char* column_name) const
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
TVariant& TRecordset::get_tmp_var() const
|
||||
{
|
||||
static TArray _page; // Variants to be returned by get
|
||||
@ -510,6 +511,7 @@ TVariant& TRecordset::get_tmp_var() const
|
||||
_next_var++;
|
||||
return *var;
|
||||
}
|
||||
*/
|
||||
|
||||
const TVariant& TRecordset::get(const char* column_name) const
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ protected:
|
||||
|
||||
void find_and_reset_vars();
|
||||
void parsed_text(TString& sql) const;
|
||||
TVariant& get_tmp_var() const;
|
||||
//TVariant& get_tmp_var() const;
|
||||
bool export_dbf(int logicnum);
|
||||
|
||||
public: // Absolutely needed methods
|
||||
|
@ -396,3 +396,27 @@ bool TVariant_stack::overflow() const
|
||||
{
|
||||
return _sp > 2048;
|
||||
}
|
||||
|
||||
|
||||
// Temporary variant generator: a little step for a man, a variant step for campo!
|
||||
|
||||
TVariant& get_tmp_var()
|
||||
{
|
||||
static TArray ararar(1024);
|
||||
static int next = 0;
|
||||
|
||||
TVariant* var = dynamic_cast<TVariant*>(ararar.objptr(next));
|
||||
if (var == nullptr)
|
||||
{
|
||||
var = new TVariant(NULL_VARIANT);
|
||||
ararar.add(var, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
var->set_null();
|
||||
}
|
||||
|
||||
if (++next >= ararar.size())
|
||||
next = 0;
|
||||
return *var;
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ public:
|
||||
TVariant_stack() : _sp(0) { }
|
||||
};
|
||||
|
||||
TVariant& get_tmp_var();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -644,9 +644,13 @@ void TRilprod_mask::load_prod_file(const char* nomefile, bool savefile, bool onl
|
||||
TString filemask(dest);
|
||||
TString_array arr;
|
||||
TDate filedate(TODAY);
|
||||
time_t the_time = time(nullptr);
|
||||
struct tm local_time {};
|
||||
localtime_s(&local_time, &the_time);
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
filemask << format("pr%02d%02d*.dat", filedate.month(), filedate.day());
|
||||
filemask << format("pr%04d%02d%02d%02d%02d*.dat", filedate.year(), filedate.month(), filedate.day(), local_time.tm_hour, local_time.tm_min);
|
||||
list_files(filemask, arr);
|
||||
|
||||
const int items = arr.items();
|
||||
@ -657,7 +661,7 @@ void TRilprod_mask::load_prod_file(const char* nomefile, bool savefile, bool onl
|
||||
}
|
||||
cnt++;
|
||||
|
||||
dest << format("pr%02d%02d%02d.dat", filedate.month(), filedate.day(), cnt);
|
||||
dest << format("pr%04d%02d%02d%02d%02d%02d.dat", filedate.year(), filedate.month(), filedate.day(), local_time.tm_hour, local_time.tm_min, cnt);
|
||||
if (fcopy(nomefile, dest))
|
||||
remove_file(nomefile);
|
||||
|
||||
|
@ -125,6 +125,11 @@ int TCache_art::get_extra_info(const char* key, TArticolo_pack& art)
|
||||
const TString& sc = envtax.get(0u).as_string();
|
||||
const real wkg = envtax.get(1).as_real();
|
||||
const TCONAI_class cc = conai_str2class(sc);
|
||||
if (cc == TCONAI_class::CONAI_NONE)
|
||||
{
|
||||
TString err = "ATTENZIONE!! Classe conai errata per articolo "; err << article_code;
|
||||
warning_box(err);
|
||||
}
|
||||
if (art.set_conai(cc, sc, wkg))
|
||||
info = 2;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user