Patch level : 12.0 412
Files correlati : Commento : Maschera: - Aggiunte funzioni controllo date filtro - Modificato filtro "fatture da visualizzare" - Aggiornata maschera sheet per i nuovi filtri Programma: - Spezzato in 3 files, stava diventando ingestibile, VS non linkava più molte funzioni. - 1: Main App & Utilities - 2: Maschera - 3: Query campo e SQLite - Tolte inclusioni non usate - Tolto membro statico a 2 funzioni che non aveva per niente senso - Resa inline la funzione toDate - Tolte variabili inutilizzate - Sistemato riempimento anagrafiche di tutti ditta, clifo, rfso. - Aggiornata gestione bolle doganali, adesso mette come PIVA OO99999999999 - Aggiornato filtri nelle query di campo git-svn-id: svn://10.65.10.50/branches/R_10_00@23928 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
94bc9d47be
commit
5eaf4d01f8
1268
src/tf/tf0100.cpp
1268
src/tf/tf0100.cpp
File diff suppressed because it is too large
Load Diff
@ -40,12 +40,16 @@ DATE F_DATAINI
|
||||
BEGIN
|
||||
PROMPT 1 1 "Data iniziale:"
|
||||
CHECKTYPE REQUIRED
|
||||
VALIDATE DATE_CMP_FUNC <= F_DATAFIN
|
||||
WARNING "La data iniziale non può essere maggiore della data finale"
|
||||
END
|
||||
|
||||
DATE F_DATAFIN
|
||||
BEGIN
|
||||
PROMPT 40 1 "Data Finale: "
|
||||
CHECKTYPE REQUIRED
|
||||
VALIDATE DATE_CMP_FUNC >= F_DATAINI
|
||||
WARNING "La data finale non può essere minore della data iniziale"
|
||||
END
|
||||
|
||||
RADIOBUTTON F_TIPOCF 15
|
||||
@ -95,7 +99,7 @@ BEGIN
|
||||
PROMPT 1 6 "Fatture da visualizzare"
|
||||
ITEM "0|Da inviare"
|
||||
ITEM "1|Inviate"
|
||||
ITEM "2|Tutti"
|
||||
ITEM "2|Disabilitate"
|
||||
END
|
||||
|
||||
GROUPBOX DLG_NULL 65 4
|
||||
@ -195,7 +199,7 @@ LIST A_INVIO 1 15
|
||||
BEGIN
|
||||
PROMPT 1 10 "Da inviare"
|
||||
ITEM "X|Da Inviare"
|
||||
ITEM "N|Da non inviare"
|
||||
ITEM "N|Disabilitato"
|
||||
ITEM "F|Forzato"
|
||||
ITEM "E|Errato"
|
||||
FIELD INVIO
|
||||
@ -203,7 +207,7 @@ END
|
||||
|
||||
BOOLEAN A_FORZATA
|
||||
BEGIN
|
||||
PROMPT 25 10 "Forzatura manuale"
|
||||
PROMPT 30 10 "Forzatura manuale"
|
||||
FIELD FORZATURA
|
||||
END
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <utility.h>
|
||||
#include <agasys.h>
|
||||
#include <printer.h>
|
||||
#include <dongle.h> // dongle()
|
||||
#include <odbcrset.h> // Oracle Recset
|
||||
|
||||
#include <map> // std::map
|
||||
|
||||
@ -33,11 +35,12 @@ enum return_code
|
||||
after // File mov su un movimento dopo rispetto a rmoviva
|
||||
};
|
||||
|
||||
// Su DB: X o ''->Da inviare, F->Forzato, I->Inviato, N->Non inviare
|
||||
enum filter_fatt
|
||||
{
|
||||
toSend, // Da inviare
|
||||
sent, // Inviate
|
||||
all // Tutte
|
||||
toSend, // Da inviare
|
||||
sent, // Inviate
|
||||
disabled // Disabilitate
|
||||
};
|
||||
|
||||
#define MOV_CUSTOM 10000000
|
||||
@ -94,13 +97,13 @@ TRectype getCli(TString tipocf, TString codcf);
|
||||
// Cerca una stringa all'interno di una SLIST (Potrebbe diventare una funzione di XVT.h)
|
||||
static SLIST_ELT xvt_slist_find_str(SLIST list, const char* str);
|
||||
// Controlla se l'azienda ha un RFSO
|
||||
static bool haveRFSO(TString& codrfso);
|
||||
bool haveRFSO(TString& codrfso);
|
||||
// Decodifica il tipo di documento per il trasferimento fatture
|
||||
static const char* decodTipo(TToken_string* strarr);
|
||||
const char * decodTipo(TToken_string* strarr);
|
||||
// Salvo un singolo record
|
||||
bool saveRec(TToken_string row, bool esportato = false);
|
||||
// Ritorno una data in formato ANSI
|
||||
TDate toDate(const char * date) { return TDate(date).string(); }
|
||||
inline TDate toDate(const char * date) { return TDate(date).string(); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// TTrFa_record
|
||||
@ -153,18 +156,16 @@ class TTrFa_cursors : TObject
|
||||
friend class TCursor;
|
||||
TISAM_recordset* c_rmoviva;
|
||||
TISAM_recordset* c_trasfatt;
|
||||
filter_fatt filFat;
|
||||
bool _newMov;
|
||||
bool _newCust;
|
||||
// Se trovo un record custom devo saltare tutti quelli che trovo successivamente, per fare ciò utilizzo una TToken_string
|
||||
TToken_string _alqCust;
|
||||
|
||||
bool filOk(bool alreadySent) { return (filFat == all) || (filFat == sent && alreadySent) || (filFat == toSend && !alreadySent); }
|
||||
TRectype _next(return_code& code, TString& tipocf, TString& codcf); // Si sposta avanti di un elemento
|
||||
TRectype _nextCust(return_code& code, TString& tipocf, TString& codcf); // Si sposta avanti di un elemento tra quelli custom
|
||||
bool checkRecord(TISAM_recordset* rec);
|
||||
public:
|
||||
TTrFa_cursors() : filFat(all) {};
|
||||
//TTrFa_cursors();
|
||||
~TTrFa_cursors();
|
||||
long int getIvaItems() { return c_rmoviva->items(); }
|
||||
long int getIvaPos() { return c_rmoviva->cursor()->pos(); }
|
||||
|
665
src/tf/tf0101.cpp
Normal file
665
src/tf/tf0101.cpp
Normal file
@ -0,0 +1,665 @@
|
||||
/* Gestione maschera */
|
||||
|
||||
#include "tf0100b.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// TTrFa_mask
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TTrFa_mask::~TTrFa_mask()
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
if(!sheet.empty())
|
||||
sheet.destroy();
|
||||
}
|
||||
|
||||
void TTrFa_mask::next_page(int p)
|
||||
{
|
||||
TAutomask::next_page(p);
|
||||
if (_filter_changed)
|
||||
{
|
||||
TSheet_field & sf = sfield(F_RIGHE);
|
||||
if (curr_win() == sf.parent())
|
||||
{
|
||||
load_sheet();
|
||||
sf.force_update();
|
||||
_filter_changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TTrFa_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||||
{
|
||||
switch (o.dlg())
|
||||
{
|
||||
case F_DATAINI:
|
||||
if (e == fe_init)
|
||||
o.set(ini_get_string(CONFIG_DITTA, "tf", "LastSend", "01-01-2017"));
|
||||
break;
|
||||
case F_DATAFIN:
|
||||
if (e == fe_init)
|
||||
o.set(TDate(TODAY));
|
||||
break;
|
||||
case DLG_ALL:
|
||||
if (e == fe_button)
|
||||
{
|
||||
TSheet_field& docs = sfield(F_RIGHE);
|
||||
TString_array& sht = docs.rows_array();
|
||||
const int items = sht.items();
|
||||
|
||||
if (items > 0)
|
||||
{
|
||||
const TString4 select = *(sht.row(0).get(0)) == 'X' ? "" : "X";
|
||||
for (int i = 0; i < items; i++)
|
||||
sht.row(i).add(select, 0);
|
||||
docs.force_update();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_RIGHE:
|
||||
if (e == se_notify_add)
|
||||
{
|
||||
TSheet_field& s = (TSheet_field&)o;
|
||||
TToken_string& row = s.row(jolly);
|
||||
row.add(nuovo_progr(), s.cid2index(A_NUMERO));
|
||||
} else
|
||||
if (e == se_query_del)
|
||||
{
|
||||
TSheet_field& s = (TSheet_field&)o;
|
||||
TToken_string& row = s.row(jolly);
|
||||
const TRecnotype progr = row.get_long(0);
|
||||
return progr >= MOV_CUSTOM;
|
||||
} else
|
||||
if(e == se_enter)
|
||||
{
|
||||
//primaNota(o,e);
|
||||
}
|
||||
break;
|
||||
case A_DATAREG:
|
||||
{
|
||||
// Mi interessa solo fe_edit
|
||||
if(e != fe_modify) break;
|
||||
// Controllo che la data sia < della data documento e l'esercizio sia quello richiesto
|
||||
TDate datareg = o.get(), datadoc = o.mask().get(A_DATADOC);
|
||||
if(datareg >= get_date(F_DATAINI) && datareg <= get_date(F_DATAFIN))
|
||||
{
|
||||
// Controllo la data del documento
|
||||
if(datadoc.ok())
|
||||
{
|
||||
if(datadoc > datareg)
|
||||
{
|
||||
error_box("La data del documento è antecedente a quella di registrazione");
|
||||
o.set("");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_box("La data di registrazione non appartiene al periodo corrente");
|
||||
o.set("");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case A_DATADOC:
|
||||
{
|
||||
// Mi interessa solo fe_edit
|
||||
if(e != fe_modify) break;
|
||||
TDate datareg = o.mask().get(A_DATAREG), datadoc = o.get();
|
||||
// Controllo la data di registrazione
|
||||
if(datareg.ok())
|
||||
{
|
||||
if(datadoc > datareg)
|
||||
{
|
||||
error_box("La data del documento è antecedente a quella di registrazione");
|
||||
o.set("");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case A_ALIQUOTA:
|
||||
if(e == fe_modify)
|
||||
{
|
||||
// Calcolo la natura
|
||||
o.mask().set(A_NATURA, natura(o.get()));
|
||||
// Se esiste un imponibile calcolo l'imposta
|
||||
real imponibile = o.mask().get(A_IMPONIBILE), imposta = ZERO;
|
||||
if(imponibile > 0)
|
||||
{
|
||||
imposta = imponibile * real(cache().get("%IVA", o.get(), "R0")) / 100;
|
||||
o.mask().set(A_IMPOSTA, imposta.round(2).string());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case A_IMPONIBILE:
|
||||
if(e == fe_modify)
|
||||
{
|
||||
// Se esiste l'iva calcolo l'imposta
|
||||
real imponibile = o.get(), imposta = ZERO;
|
||||
TString codiva = o.mask().get(A_ALIQUOTA);
|
||||
if(codiva != "")
|
||||
{
|
||||
imposta = imponibile * real(cache().get("%IVA", codiva, "R0")) / 100;
|
||||
o.mask().set(A_IMPOSTA, imposta.round(2).string());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case A_IMPOSTA:
|
||||
if(e == fe_modify)
|
||||
{
|
||||
// Controllo dell'esistenza sia di codiva che dell'imponibile e verifico che l'importo immesso sia corretto
|
||||
real imponibile = o.mask().get(A_IMPONIBILE), imposta = ZERO;
|
||||
TString codiva = o.mask().get(A_ALIQUOTA);
|
||||
if(codiva != "" && imponibile > ZERO)
|
||||
{
|
||||
imposta = imponibile * real(cache().get("%IVA", codiva, "R0")) / 100; imposta = imposta.round(2);
|
||||
// Controllo che l'aliquota calcolata sia == a quella che ho qua
|
||||
real impostaInserita = o.get();
|
||||
if(impostaInserita != imposta)
|
||||
{
|
||||
TString msg;
|
||||
msg << "Attenzione!! Il valore immesso " << impostaInserita.string() << "€ non è corretto!\n";
|
||||
msg << "Valore corretto: " << imposta.string() << "€\nVuoi proseguire?";
|
||||
if(!yesno_box(msg))
|
||||
{
|
||||
o.set(imposta.string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case A_TIPOCF:
|
||||
case A_CODCF:
|
||||
case A_OCFPI:
|
||||
{
|
||||
if(e != fe_modify) break;
|
||||
TString tipocf, codcf;
|
||||
// Controllo se è un cliente occasionale
|
||||
tipocf = "O";
|
||||
codcf = o.mask().get(A_OCFPI);
|
||||
if(codcf.empty())
|
||||
{
|
||||
tipocf = o.mask().get(A_TIPOCF);
|
||||
codcf = o.mask().get(A_CODCF);
|
||||
}
|
||||
TRectype app = getCli(tipocf, codcf);
|
||||
o.mask().set(A_RAGSOC, app.get("RAGSOC"));
|
||||
o.mask().set(A_RFSO, app.get("CODRFSO"));
|
||||
o.mask().set(A_RAGSOCRFSO, getRFSO(app.get("CODRFSO")));
|
||||
o.mask().set(A_PAIV, app.get("PAIV"));
|
||||
o.mask().set(A_COFI, app.get("COFI"));
|
||||
|
||||
// Controllo autofattura
|
||||
TString key; key << prefix().firm().get("TIPOA") << "|" << prefix().firm().get("CODANAGR");
|
||||
TString piva = cache().get(LF_ANAG, key, "PAIV");
|
||||
if(piva == app.get("PAIV"))
|
||||
{
|
||||
// Autofattura!
|
||||
o.mask().set(A_AUTOFATT, "X");
|
||||
}
|
||||
}
|
||||
case DLG_SAVEREC:
|
||||
if(e == fe_button)
|
||||
saveAll();
|
||||
break;
|
||||
case DLG_ARCHIVE:
|
||||
if(e == fe_button)
|
||||
checkAll();
|
||||
break;
|
||||
case DLG_EDIT:
|
||||
if(e == fe_button)
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
if(sheet.items() > 0)
|
||||
{
|
||||
sheet.esporta();
|
||||
}
|
||||
else
|
||||
{
|
||||
warning_box("Impossibile esportare una griglia vuota");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DLG_RECALC:
|
||||
if(e == fe_button)
|
||||
next_page(1);
|
||||
break;
|
||||
case DLG_USER:
|
||||
if (e == fe_button || e == fe_init)
|
||||
{
|
||||
const long numreg = o.mask().get_long(A_NUMERO);
|
||||
const bool enab = (numreg > 0) && (numreg < MOV_CUSTOM);
|
||||
if (e == fe_button && enab)
|
||||
{
|
||||
o.disable(); // Tecnica anti doppio click!
|
||||
TRectype mov(LF_MOV);
|
||||
mov.put("NUMREG", numreg);
|
||||
mov.edit();
|
||||
o.enable();
|
||||
}
|
||||
else
|
||||
o.enable(enab);
|
||||
}
|
||||
break;
|
||||
case DLG_DELREC:
|
||||
if (e == fe_button && o.active())
|
||||
{
|
||||
const long progr = o.mask().get_long(A_NUMERO);
|
||||
TString codalq = o.mask().get(A_ALIQUOTA);
|
||||
TString key; key << progr << "|" << codalq;
|
||||
if (progr >= MOV_CUSTOM)
|
||||
{
|
||||
if(cache().get(LF_TRASFATT, key).full())
|
||||
{
|
||||
TLocalisamfile trasfat(LF_TRASFATT);
|
||||
trasfat.put("NUMREG", progr);
|
||||
trasfat.put("CODIVA", codalq);
|
||||
const int err = trasfat.remove();
|
||||
if (err != NOERR)
|
||||
return error_box(FR("Errore di cancellazione: %d"), err);
|
||||
}
|
||||
// In qualsiasi caso elimino sta riga
|
||||
TSheet_field& s = o.mask().sfield(F_RIGHE);
|
||||
TToken_string& row = s.row(jolly);
|
||||
row.destroy(jolly);
|
||||
}
|
||||
else
|
||||
return error_box(TR("Riga non cancellabile"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const short id = o.dlg();
|
||||
if (e == fe_modify && jolly == 1)
|
||||
{
|
||||
if (id >= START_SHEET && id < END_SHEET && id != A_FORZATA)
|
||||
{
|
||||
// Se ho modificato l'impostazione dell'invio non va segnata la modifica MA devo togliere o mettere il flag a tutti quelli con movimento uguale
|
||||
if(id != A_INVIO)
|
||||
o.mask().set(A_FORZATA, true);
|
||||
else
|
||||
{
|
||||
changeInvio(o.mask().get(A_TIPOCF), o.mask().get(A_CODCF), o.mask().get(A_NUMDOC), o.mask().get(A_INVIO));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e == fe_modify && jolly == 0)
|
||||
{
|
||||
if (id >= START_MASK && id <= END_MASK)
|
||||
{
|
||||
setFilterChanged();
|
||||
}
|
||||
if(id >= START_BOOLEAN && id <= END_BOOLEAN)
|
||||
saveConfig();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TTrFa_mask::loadConfig()
|
||||
{
|
||||
// Rilevo i tipi scelti
|
||||
TToken_string tipidoc(ini_get_string(CONFIG_DITTA, "tf", "TIPIDOC"));
|
||||
// Potrei fare un for su TToken_string ma non darebbe la possibilità di flaggare tutto in caso di prima installazione
|
||||
for(int pos = 0; pos < tipidoc.items(); pos++)
|
||||
{
|
||||
int field = getTipoDoc(tipidoc.get(pos));
|
||||
if(field != -1)
|
||||
set(field, "X");
|
||||
}
|
||||
}
|
||||
void TTrFa_mask::saveConfig()
|
||||
{
|
||||
TToken_string tipidoc;
|
||||
for(int id = START_BOOLEAN; id <= END_BOOLEAN; id++)
|
||||
{
|
||||
if(get_bool(id))
|
||||
{
|
||||
tipidoc.add(getTipoDoc(id));
|
||||
}
|
||||
}
|
||||
ini_set_string(CONFIG_DITTA, "tf", "TIPIDOC", tipidoc);
|
||||
}
|
||||
|
||||
/* salvo tutti i record modificati */
|
||||
bool TTrFa_mask::saveAll()
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
//TString_array& strarr = sheet.rows_array();
|
||||
TString mod = "";
|
||||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||||
{
|
||||
strarr->get(_forzata, mod);
|
||||
if(mod == "X")
|
||||
{
|
||||
bool ok, retry = false;
|
||||
do
|
||||
{
|
||||
ok = saveRec(*strarr);
|
||||
if(!ok)
|
||||
{
|
||||
TString msg = "Errore durante il salvataggio del movimento ";
|
||||
msg << "alla riga " << r << "\nRitentare?";
|
||||
retry = yesno_box(msg);
|
||||
}
|
||||
} while(retry && !ok);
|
||||
if(!ok)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TTrFa_mask::checkAll()
|
||||
{
|
||||
// Controllo di avere uno sheet pieno
|
||||
if(!checkNotEmpty()) return true;
|
||||
|
||||
if(yesno_box("Controllare tutti i C.F. P.IVA?"))
|
||||
{
|
||||
TExternal_app servizio("cg1 -2 L");
|
||||
servizio.run();
|
||||
}
|
||||
|
||||
// Sistemo i flag
|
||||
theFinalCheckDown();
|
||||
|
||||
static TPrinter stampa;
|
||||
stampa.reset();
|
||||
stampa.open();
|
||||
TPrintrow riga;
|
||||
riga.put(TR("------------------ Controllo Errori TF -------------------"), 30);
|
||||
stampa.setheaderline(1, riga);
|
||||
riga.reset();
|
||||
riga.put("N.Registrazione", 0);
|
||||
riga.put("N.Documento", 20);
|
||||
riga.put("Tipo errore", 40);
|
||||
stampa.setheaderline(3, riga);
|
||||
riga.reset();
|
||||
riga.put(TR("Tutti i record qui elencati sono stati segnati con il codice \"Errore\" e non verranno inviati"), 0);
|
||||
stampa.setheaderline(2, riga);
|
||||
riga.reset();
|
||||
stampa.setheaderline(4, riga);
|
||||
stampa.print(riga);
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||||
{
|
||||
checkRec(&stampa, *strarr);
|
||||
}
|
||||
riga.reset();
|
||||
riga.put(TR("------------------ Fine controllo! ------------------"), 30);
|
||||
stampa.print(riga);
|
||||
stampa.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void printError(TPrinter* stampa, TString movimento, TString documento, TString msgerr)
|
||||
{
|
||||
TPrintrow riga;
|
||||
riga.put(movimento, 0);
|
||||
riga.put(documento, 20);
|
||||
riga.put(msgerr, 40);
|
||||
stampa->print(riga);
|
||||
}
|
||||
|
||||
bool TTrFa_mask::checkRec(TPrinter* stampa, TToken_string rec)
|
||||
{
|
||||
bool ok = true;
|
||||
TString numMov = rec.get(_numero), numDoc = rec.get(_numdoc);
|
||||
TString msgerr;
|
||||
TString coderr;
|
||||
// Controllo date ***********************************************************************************
|
||||
TDate reg = rec.get(_datareg), doc = rec.get(_datadoc);
|
||||
if(reg < doc)
|
||||
{
|
||||
ok = false;
|
||||
msgerr.cut(0) << "Data registrazione precedente alla data del documento";
|
||||
printError(stampa, numMov, numDoc, msgerr);
|
||||
coderr << "1;";
|
||||
}
|
||||
|
||||
// Controllo aliquota, imponibile e imposta *********************************************************
|
||||
TCodiceIVA codiva(rec.get(_aliquota));
|
||||
TString nat = rec.get(_natura), realNat(natura(rec.get(_aliquota)));
|
||||
nat.ltrim(); // Se vuoto arriva con uno spazio
|
||||
real imponibile = rec.get(_imponibile), imposta = rec.get(_importoIVA);
|
||||
if(nat != realNat)
|
||||
{
|
||||
msgerr.cut(0) << "Natura del movimento errata, valore dichiarato: " << nat << " valore corretto: " << realNat;
|
||||
printError(stampa, numMov, numDoc, msgerr);
|
||||
coderr << "2;";
|
||||
}
|
||||
|
||||
real realImp = imponibile * codiva.percentuale() / CENTO;
|
||||
realImp.round(2);
|
||||
if(imposta > realImp + TOLLARANZA || imposta < realImp - TOLLARANZA)
|
||||
{
|
||||
msgerr.cut(0) << "Imposta errata, valore dichiarato: " << imposta.string() << " valore \"potenzialmente\" corretto: " << realImp.string();
|
||||
printError(stampa, numMov, numDoc, msgerr);
|
||||
coderr << "3;";
|
||||
}
|
||||
|
||||
// Controllo Stato ***********************************************************************************
|
||||
/*
|
||||
TRectype clifo = getCli(rec.get(_tipocf), rec.get(_codcf));
|
||||
if(clifo.get("STATOCF") == "" &&
|
||||
*/
|
||||
// Flaggo il record con i messaggi di errore
|
||||
if(!ok)
|
||||
{
|
||||
rec.add("E", _invio);
|
||||
rec.add(coderr, _coderr);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TTrFa_mask::checkNotEmpty()
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
TString msg;
|
||||
|
||||
if(sheet.empty())
|
||||
msg = "La tabella dei movimenti è vuota, vuoi caricarla con i filtri selezionati?";
|
||||
else if(_filter_changed)
|
||||
msg = "I filtri sono stati cambiati, vuoi ricaricare la tabella con i nuovi filtri selezionati?";
|
||||
|
||||
if(msg.full() && yesno_box(msg))
|
||||
{
|
||||
_filter_changed = false;
|
||||
load_sheet();
|
||||
}
|
||||
return sheet.full();
|
||||
}
|
||||
|
||||
void TTrFa_mask::theFinalCheckDown()
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
TAssoc_array cliDocs;
|
||||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||||
{
|
||||
// Chiave: TIPOCF + CODCF + NUMDOC + CODIVA
|
||||
TString key; key << strarr->get_char(_tipocf) << "|" << strarr->get_int(_codcf) << "|" << strarr->get(_numdoc) << "|" << strarr->get(_aliquota);
|
||||
TToken_string newNumero; newNumero.add(r, 0); newNumero.add(strarr->get_char(_invio), 1);
|
||||
if(cliDocs.is_key(key))
|
||||
{
|
||||
TToken_string oldnumero = *(TToken_string*)cliDocs.objptr(key);
|
||||
TString oldflag; oldnumero.get(1, oldflag);
|
||||
if(oldflag == FLAG_FORZATO)
|
||||
flagRow(r, FLAG_NINVIO);
|
||||
else
|
||||
{
|
||||
int oldr; oldnumero.get(0, oldr);
|
||||
flagRow(oldr, FLAG_NINVIO);
|
||||
}
|
||||
|
||||
cliDocs.add(key, newNumero);
|
||||
}
|
||||
else
|
||||
{
|
||||
cliDocs.add(key, newNumero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrFa_mask::flagRow(int nrow, TString flag)
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
TToken_string& row = sheet.row(nrow);
|
||||
row.add(flag, _invio);
|
||||
}
|
||||
|
||||
TRecnotype TTrFa_mask::nuovo_progr() const
|
||||
{
|
||||
static TRectype app(LF_TRASFATT);
|
||||
app.last(TLocalisamfile(LF_TRASFATT));
|
||||
// Lo inizializzo solo la prima volta poi incremento
|
||||
static TRecnotype numreg = app.get_long("NUMREG") > MOV_CUSTOM ? app.get_long("NUMREG") : MOV_CUSTOM;
|
||||
numreg++;
|
||||
return numreg;
|
||||
}
|
||||
|
||||
// Dato un cliente e il suo numero documento imposto il nuovo flag di invio su tutti i campi
|
||||
void TTrFa_mask::changeInvio(TString tipocf, TString codcf, TString numdoc, TString invio) const
|
||||
{
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
TString rtipo, rcod, rnum;
|
||||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||||
{
|
||||
// Ricevo i parametri della riga
|
||||
rtipo.cut(0); rtipo << strarr->get_char(_tipocf);
|
||||
rcod.cut(0); rcod << strarr->get_int(_codcf);
|
||||
rnum.cut(0); rnum << strarr->get(_numdoc);
|
||||
if(tipocf == rtipo && codcf == rcod && rnum == numdoc)
|
||||
{
|
||||
strarr->add(invio, _invio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrFa_mask::load_sheet()
|
||||
{
|
||||
const char tipo = get(F_TIPOCF)[0];
|
||||
const long codice = get_long(F_CODCF);
|
||||
TDate dal = get_date(F_DATAINI), al = get_date(F_DATAFIN);
|
||||
//TString key; key << "TIPOA=" << prefix().firm().get("TIPOA")<< ",CODANAGR=" << prefix().firm().get("CODANAGR");
|
||||
TString key; key << prefix().firm().get("TIPOA") << "|" << prefix().firm().get("CODANAGR");
|
||||
const TString pivaDitta = cache().get(LF_ANAG, key, "PAIV");
|
||||
const TString cofiDitta = cache().get(LF_ANAG, key, "COFI");
|
||||
|
||||
TTrFa_cursors c;
|
||||
|
||||
TSheet_field& sheet = sfield(F_RIGHE);
|
||||
TString_array& strarr = sheet.rows_array();
|
||||
|
||||
sheet.hide(); // Nascondo lo sheet per guadagnare un 20% di velocità di caricamento, le ottimizzazioni da PRO!
|
||||
if(!sheet.empty())
|
||||
sheet.destroy();
|
||||
TAssoc_array recimposte;
|
||||
int items = c.updateFilters(tipo, codice, dal, al, get_int(F_FATTSEL));
|
||||
for(bool ok = true; items > 0 && ok;)
|
||||
{
|
||||
TString tipocf, codcf;
|
||||
int err = c.next(recimposte, ok, tipocf, codcf);
|
||||
// Carico i clienti
|
||||
TRectype cli = getCli(tipocf, codcf);
|
||||
|
||||
FOR_EACH_ASSOC_OBJECT(recimposte, h, iva, rec)
|
||||
{
|
||||
TToken_string* row = new TToken_string;
|
||||
TRectype movimento = *(TRectype*)rec;
|
||||
|
||||
// Controllo che sia un tipo documento da leggere
|
||||
if(!get_bool(getTipoDoc(movimento.get("TIPODOC")))) continue;
|
||||
|
||||
/* Siccome mi cambiano l'ordine ogni volta e non ho voglia di cambiare tutto ovunque
|
||||
* basta settare i valori negli enum e lo sheet
|
||||
*/
|
||||
TRectype isCust = getTrasFatt(movimento.get("NUMREG"), iva);
|
||||
|
||||
row->add(isCust.get_bool("TFINVIO") ? "X" : "", _spedita); // Spedita
|
||||
row->add("X"); // Da spedire, sempre!
|
||||
row->add(isCust.full() ? "X" : "", _forzata); // Modificato
|
||||
row->add(movimento.get_long("NUMREG"), _numero); // Numero registrazione
|
||||
row->add(movimento.get_date("DATAREG"), _datareg); // Data Registrazione
|
||||
row->add(movimento.get("TIPO"), _tipocf); // Tipo Cli/For
|
||||
row->add(movimento.get("CODCF"), _codcf); // Codice Cli/For
|
||||
row->add(movimento.get("OCCAS"), _occas); // Codice Occasionale
|
||||
row->add(cli.get("RAGSOC"), _ragsoc); // Ragione sociale
|
||||
row->add(cli.get("CODRFSO"), _rfso); // Codice RF/SO
|
||||
row->add(getRFSO(cli.get("CODRFSO")), _ragsocrfso); // Ragione Sociale RF/SO
|
||||
row->add(movimento.get("TIPODOC"), _codnum); // Tipo documento
|
||||
row->add(movimento.get("NUMDOC"), _numdoc); // Numero documento
|
||||
row->add(movimento.get_date("DATADOC"), _datadoc); // Data documento
|
||||
row->add(natura(iva), _natura); // NATURA!
|
||||
row->add(iva, _aliquota); // Codice aliquota!
|
||||
row->add(findDetraib(movimento.get("TIPODET")), _detraibile); // Detraibilità
|
||||
row->add(movimento.get_real("IMPONIBILE"), _imponibile); // Imponibile
|
||||
row->add(movimento.get_real("IMPOSTA"), _importoIVA); // Imposta
|
||||
row->add(revCharge(movimento.get("NUMREG")), _reverse); // Rev.Charge
|
||||
|
||||
/*
|
||||
* Possono esistere movimenti custom dove il cliente ha una partita IVA propria
|
||||
* ma è stato flaggato l'autofattura, quindi in trasfat è presente il codice cliente con PIVA e CODFIS della ditta.
|
||||
* Controllo sia il movimento che il cliente
|
||||
*/
|
||||
if(movimento.get("AUTOFATT") == "X" || pivaDitta == cli.get("PAIV")) // Se è un autofattura
|
||||
{
|
||||
row->add("X", _autofatt); // AutoFatt
|
||||
row->add(pivaDitta, _paiv); // P.IVA
|
||||
row->add(cofiDitta, _codfis); // Codice Fiscale
|
||||
}
|
||||
else
|
||||
{
|
||||
row->add("", _autofatt); // AutoFatt
|
||||
row->add(cli.get("PAIV"), _paiv); // P.IVA
|
||||
row->add(cli.get("COFI"), _codfis); // Codice Fiscale
|
||||
}
|
||||
|
||||
strarr.add(row);
|
||||
}
|
||||
recimposte.destroy();
|
||||
}
|
||||
sheet.force_update();
|
||||
sheet.show();
|
||||
}
|
||||
|
||||
TString TTrFa_mask::findDetraib(TString tipodet) const
|
||||
{
|
||||
real perc = cache().get("%DET", tipodet, "R0");
|
||||
return perc.stringa(6,2);
|
||||
}
|
||||
|
||||
const char * TTrFa_mask::natura(const TString& codiva) const
|
||||
{
|
||||
const TRectype& ai = cache().get("%IVA", codiva);
|
||||
TString & natura = get_tmp_string(4);
|
||||
|
||||
natura = ai.get("S12");
|
||||
return natura;
|
||||
}
|
||||
|
||||
real TTrFa_mask::get_IVA(const TString& codiva) const
|
||||
{
|
||||
const TRectype& ai = cache().get("%IVA", codiva);
|
||||
return ai.get_real("R0");
|
||||
}
|
||||
|
||||
TString TTrFa_mask::revCharge(TString numreg) const
|
||||
{
|
||||
// Controllo se la causale ha il reverse charge, se il cliente non l'ha impostata giusta sono ARAZZI suoi
|
||||
TString key = numreg;
|
||||
TCausale caus(cache().get(LF_MOV, key, "CODCAUS"));
|
||||
return caus.reverse_charge() ? "X" : "";
|
||||
}
|
||||
|
||||
TString TTrFa_mask::getRFSO(TString codrfso) const
|
||||
{
|
||||
TString key; key << codrfso[0] << "|" << codrfso.mid(1);
|
||||
return cache().get(LF_ANAG, key, "RAGSOC");
|
||||
}
|
||||
|
||||
TTrFa_mask::TTrFa_mask(TString msk)
|
||||
: TAutomask(msk), _filter_changed(true)
|
||||
{
|
||||
loadConfig();
|
||||
}
|
455
src/tf/tf0102.cpp
Normal file
455
src/tf/tf0102.cpp
Normal file
@ -0,0 +1,455 @@
|
||||
/* Query in Campo e SQLite */
|
||||
|
||||
#include "tf0100b.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// TTrFa_record
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Imposta il valore di un campo variant
|
||||
void TTrFa_record::set(const char* fld, const TVariant& var)
|
||||
{
|
||||
CHECK(fld && *fld, "Null field name");
|
||||
|
||||
if (var.is_null())
|
||||
{
|
||||
_fields.remove(fld);
|
||||
}
|
||||
else
|
||||
{
|
||||
TVariant* obj = (TVariant*)_fields.objptr(fld);
|
||||
if (obj != NULL)
|
||||
*obj = var;
|
||||
else
|
||||
_fields.add(fld, new TVariant(var));
|
||||
}
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo intero
|
||||
void TTrFa_record::set(const char* fld, long val)
|
||||
{
|
||||
const TVariant var(val);
|
||||
set(fld, var);
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo stringa
|
||||
void TTrFa_record::set(const char* fld, const char* val)
|
||||
{
|
||||
if (val == NULL)
|
||||
set(fld, NULL_VARIANT);
|
||||
else
|
||||
{
|
||||
const TVariant var(val);
|
||||
set(fld, var);
|
||||
}
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo stringa
|
||||
void TTrFa_record::set(const char* fld, const TString& val)
|
||||
{
|
||||
const TVariant var(val);
|
||||
set(fld, var);
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo numerico
|
||||
void TTrFa_record::set(const char* fld, const real& val)
|
||||
{
|
||||
const TVariant var(val);
|
||||
set(fld, var);
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo data in formato ISO
|
||||
void TTrFa_record::set(const char* fld, const TDate& val)
|
||||
{
|
||||
if (val.ok())
|
||||
{
|
||||
const TVariant var(val);
|
||||
set(fld, var);
|
||||
}
|
||||
else
|
||||
set(fld, "");
|
||||
}
|
||||
|
||||
// Imposta il valore di un campo booleano
|
||||
void TTrFa_record::set(const char* fld, bool var)
|
||||
{
|
||||
set(fld, var ? "SI" : "NO");
|
||||
}
|
||||
|
||||
// Legge il valore di un campo variant
|
||||
const TVariant& TTrFa_record::get(const char* fld) const
|
||||
{
|
||||
const TVariant* var = (const TVariant*)_fields.objptr(fld);
|
||||
return var ? *var : NULL_VARIANT;
|
||||
}
|
||||
|
||||
// Converte un variant in una stringa valida per SQLite
|
||||
const TString& TTrFa_record::var2str(const TString& fldname, const TVariant& var) const
|
||||
{
|
||||
const TFieldtypes vt = var.type();
|
||||
if (vt == _realfld)
|
||||
{
|
||||
const TCurrency v(var.as_real(), "", ZERO, fldname.find("IMPONIBILE")>0 || fldname.find("IMPOSTA")>0);
|
||||
TString& tmp = get_tmp_string();
|
||||
tmp << '\'' << v.string() << '\'';
|
||||
tmp.replace(',','.');
|
||||
return tmp;
|
||||
}
|
||||
if (vt == _datefld)
|
||||
{
|
||||
TString& tmp = get_tmp_string();
|
||||
tmp << '\'' << var.as_date().string(full, '-', full, full, amg_date) << '\'';
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const TString& str = var.as_string();
|
||||
|
||||
bool apici = vt == _alfafld;
|
||||
if (apici && str[0] != '0' && real::is_natural(str))
|
||||
apici = false;
|
||||
|
||||
if (!apici)
|
||||
return str;
|
||||
|
||||
TString& tmp = get_tmp_string();
|
||||
tmp = str;
|
||||
for (int a = str.rfind('\''); a >= 0; a--)
|
||||
{
|
||||
if (tmp[a] == '\'')
|
||||
tmp.insert("'", a);
|
||||
}
|
||||
tmp.insert("'", 0);
|
||||
tmp << '\'';
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Elimina il record in base ai campi chiave
|
||||
bool TTrFa_record::remove()
|
||||
{
|
||||
TString256 query;
|
||||
query << "DELETE FROM " << _table << " WHERE ";
|
||||
int nkf = 0;
|
||||
FOR_EACH_TOKEN(_key, fld)
|
||||
{
|
||||
const TVariant& var = get(fld);
|
||||
if (!var.is_null())
|
||||
{
|
||||
if (nkf++ > 0)
|
||||
query << " AND ";
|
||||
query << fld << '=' << var2str(fld, var) ;
|
||||
}
|
||||
}
|
||||
CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table);
|
||||
query << ';';
|
||||
return xvt_sql_execute(_db, query, NULL, 0L) > 0;
|
||||
}
|
||||
|
||||
// Callback per la sottostante funzione search()
|
||||
static int tff_search_record(void* jolly, int cols, char** values, char** names)
|
||||
{
|
||||
TTrFa_record& rec = *(TTrFa_record*)jolly;
|
||||
for (int i = 0; i < cols; i++)
|
||||
rec.set(names[i], values[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Carica un record in base ai campi chiave
|
||||
bool TTrFa_record::search()
|
||||
{
|
||||
CHECKS(_fields.items() >= _key.items(), "Can't search partial key on table ", _table);
|
||||
TString256 query;
|
||||
query << "SELECT * FROM " << _table << " WHERE ";
|
||||
FOR_EACH_TOKEN(_key, fld)
|
||||
{
|
||||
const TVariant& var = get(fld);
|
||||
if (!var.is_null())
|
||||
query << fld << '=' << var2str(fld, var) << " AND ";
|
||||
}
|
||||
query.rtrim(5);
|
||||
query << ';';
|
||||
return xvt_sql_execute(_db, query, tff_search_record, this) == 1;
|
||||
}
|
||||
|
||||
// Carica un record in base ad un massimo di 3 campi chiave
|
||||
bool TTrFa_record::search(const char* k1, const char* k2, const char* k3)
|
||||
{
|
||||
_fields.destroy();
|
||||
|
||||
set(_key.get(0), k1);
|
||||
if (k2 && *k2)
|
||||
set(_key.get(1), k2);
|
||||
if (k3 && *k3)
|
||||
set(_key.get(2), k3);
|
||||
|
||||
return search();
|
||||
}
|
||||
|
||||
// Aggiunge un record al db
|
||||
bool TTrFa_record::insert()
|
||||
{
|
||||
CHECKS(_fields.items() > _key.items(), "Can't insert empty record on table ", _table);
|
||||
|
||||
TString query, values;
|
||||
query << "INSERT INTO " << _table << "\n(";
|
||||
FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm)
|
||||
{
|
||||
const TVariant& var = get(fld);
|
||||
if (!var.is_null())
|
||||
{
|
||||
query << fld << ',';
|
||||
values << var2str(fld, var) << ',';
|
||||
}
|
||||
}
|
||||
query.rtrim(1); values.rtrim(1);
|
||||
query << ")\nVALUES (" << values << ");";
|
||||
return xvt_sql_execute(_db, query, NULL, 0L) == 1;
|
||||
}
|
||||
|
||||
// Crea un record della tabella data ed imposta i nomi dei campi chiave
|
||||
TTrFa_record::TTrFa_record(const char* table) : _table(table), _key(15, ',')
|
||||
{
|
||||
_key = ini_get_string("./tff.ini", table, "INDEX_1");
|
||||
if (_key.empty())
|
||||
{
|
||||
// Cerco di costruire i nomi della chiave cercando la K, come in P1_KEYHEADERFATT
|
||||
TConfig cfg("tff.ini", table);
|
||||
TAssoc_array& fields = cfg.list_variables();
|
||||
FOR_EACH_ASSOC_STRING(fields, obj, key, str)
|
||||
{
|
||||
if (key[3] == 'K')
|
||||
_key.add(key);
|
||||
}
|
||||
}
|
||||
CHECKS(!_key.empty_items(), "Invalid primary key for table ", table);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// TTrFa_cursors
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
TTrFa_cursors::~TTrFa_cursors()
|
||||
{
|
||||
if(c_rmoviva != NULL)
|
||||
delete c_rmoviva;
|
||||
if(c_trasfatt != NULL)
|
||||
delete c_trasfatt;
|
||||
}
|
||||
|
||||
int TTrFa_cursors::next(TAssoc_array& recimposte, bool& ok, TString& tipocf, TString& codcf)
|
||||
{
|
||||
// Azzero recimposte
|
||||
recimposte.destroy();
|
||||
// Return code
|
||||
return_code err;
|
||||
// Record
|
||||
TRectype record = _next(err, tipocf, codcf);
|
||||
if(err == eof)
|
||||
{
|
||||
record = _nextCust(err, tipocf, codcf);
|
||||
}
|
||||
while(err < nextmov)
|
||||
{
|
||||
// Se ho trovato un record custom o non trovo il suo codiva tra i record custom lo salvo
|
||||
if(recimposte.is_key(record.get("CODIVA")))
|
||||
{
|
||||
// Prelevo il record salvato
|
||||
TRectype app = *(TRectype*)recimposte.objptr(record.get("CODIVA"));
|
||||
// Aggiorno i valori
|
||||
app.put("IMPONIBILE", app.get_real("IMPONIBILE") + record.get_real("IMPONIBILE"));
|
||||
app.put("IMPOSTA", app.get_real("IMPOSTA") + record.get_real("IMPOSTA"));
|
||||
// Lo reinserisco
|
||||
recimposte.add(record.get("CODIVA"), app, true);
|
||||
}
|
||||
else // Inserisco per la prima volta
|
||||
{
|
||||
// Salvo il record nell'array
|
||||
recimposte.add(record.get("CODIVA"), record);
|
||||
}
|
||||
if(err == foundidcust) break;
|
||||
record = _next(err, tipocf, codcf);
|
||||
}
|
||||
ok = err != eofcust;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Questa funzione precarica un array associativo con il movimento diviso per codiva e lo ritorna
|
||||
*/
|
||||
TRectype TTrFa_cursors::_next(return_code& code, TString& tipocf, TString& codcf)
|
||||
{
|
||||
TString numMov = c_rmoviva->get("23.NUMREG").as_string();
|
||||
// Record di ritorno
|
||||
TRectype retRec(LF_TRASFATT);
|
||||
// Controllo che non sia il primo record del movimento
|
||||
if(_newMov)
|
||||
{
|
||||
_newMov = false;
|
||||
// Se è un cliente occasionale passo "O"
|
||||
if(c_rmoviva->get("23.OCFPI").as_string() != "")
|
||||
{
|
||||
tipocf = "O";
|
||||
codcf = c_rmoviva->get("23.OCFPI").as_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
tipocf = c_rmoviva->get("23.TIPO").as_string();
|
||||
codcf = c_rmoviva->get("23.CODCF").as_string();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TString codiva;
|
||||
do
|
||||
{
|
||||
// Se ritorna false ho finito i records
|
||||
if(!c_rmoviva->move_next())
|
||||
{
|
||||
code = eof;
|
||||
return retRec;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Controllo se ho cambiato movimento
|
||||
_newMov = numMov != c_rmoviva->get("23.NUMREG").as_string();
|
||||
}
|
||||
} // Ciclo finchè non trovo un nuovo movimento o trovo cod IVA già presi da cust
|
||||
while(!checkRecord(c_rmoviva) || (!_newMov && _alqCust.get_pos(codiva) > -1));
|
||||
}
|
||||
|
||||
// Se ho cambiato movimento ritorno, leggerò poi al prossimo giro
|
||||
if(_newMov)
|
||||
{
|
||||
_alqCust.cut(0);
|
||||
code = nextmov;
|
||||
return retRec;
|
||||
}
|
||||
else
|
||||
code = found;
|
||||
|
||||
// Controllo dell'esistenza di un record custom in tasfatt
|
||||
retRec = getTrasFatt(c_rmoviva->get("23.NUMREG").as_string(), c_rmoviva->get("25.CODIVA").as_string());
|
||||
if(retRec.empty())
|
||||
{
|
||||
code = found;
|
||||
// Carico il record
|
||||
retRec.put("NUMREG", c_rmoviva->get("23.NUMREG").as_int());
|
||||
retRec.put("TIPO", c_rmoviva->get("23.TIPO").as_string());
|
||||
retRec.put("CODCF", c_rmoviva->get("23.CODCF").as_string());
|
||||
retRec.put("OCCAS", c_rmoviva->get("23.OCFPI").as_string());
|
||||
retRec.put("TIPODOC", c_rmoviva->get("23.TIPODOC").as_string());
|
||||
retRec.put("NUMDOC", c_rmoviva->get("23.NUMDOC").as_string());
|
||||
retRec.put("DATAREG", c_rmoviva->get("23.DATAREG").as_date());
|
||||
retRec.put("DATADOC", c_rmoviva->get("23.DATADOC").as_date());
|
||||
retRec.put("IMPONIBILE", c_rmoviva->get("25.IMPONIBILE").as_real());
|
||||
retRec.put("IMPOSTA", c_rmoviva->get("25.IMPOSTA").as_real());
|
||||
retRec.put("CODIVA", c_rmoviva->get("25.CODIVA").as_string());
|
||||
retRec.put("TIPODET", c_rmoviva->get("25.TIPODET").as_string());
|
||||
}
|
||||
else
|
||||
{
|
||||
_alqCust.add(c_rmoviva->get("25.CODIVA").as_string());
|
||||
code = foundcust;
|
||||
}
|
||||
return retRec;
|
||||
}
|
||||
|
||||
TRectype TTrFa_cursors::_nextCust(return_code& code, TString& tipocf, TString& codcf)
|
||||
{
|
||||
bool ok;
|
||||
// Preparo il nuovo cursore
|
||||
if(_newCust)
|
||||
{
|
||||
ok = c_trasfatt->move_first();
|
||||
_newCust = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = c_trasfatt->move_next();
|
||||
}
|
||||
tipocf = c_trasfatt->get("TIPO").as_string();
|
||||
codcf = c_trasfatt->get("CODCF").as_string();
|
||||
code = ok ? foundidcust : eofcust;
|
||||
return c_trasfatt->cursor()->curr();
|
||||
}
|
||||
|
||||
/* Utilizzo questa funzione per filtrare al meglio i record, tutti i casi che devo omettere verranno rilevati e ritorneranno false
|
||||
* Nota bene: viene sfruttato un puntatore di TISA_Recordset per non creare nuovi oggetti e velocizzare la chiamata
|
||||
* a questo punto il programma non ha ancora creato un record di $trasfatt con i dati che mi interessano
|
||||
*/
|
||||
bool TTrFa_cursors::checkRecord(TISAM_recordset* rec)
|
||||
{
|
||||
|
||||
TString keyClifo; keyClifo << rec->get("23.TIPO").as_string() << "|" << rec->get("23.CODCF").as_string();
|
||||
// Salto le schede carburanti
|
||||
if(cache().get(LF_CLIFO, keyClifo, "ALLEG") == "C")
|
||||
return false;
|
||||
|
||||
// Clienti
|
||||
if(rec->get("23.TIPO").as_string() == "C")
|
||||
{
|
||||
// Tolgo tutti i movimenti di sola IVA e in reverse charge o di tipo 3 (Acquisto di beni e servizi di soggetti non residenti)
|
||||
TCausale caus(rec->get("23.CODCAUS").as_string());
|
||||
if(caus.soloiva() && (caus.reverse_charge() || caus.regime_speciale() == 3))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int TTrFa_cursors::updateFilters(const char tipocf, const long codcf, TDate dal, TDate al, int cod)
|
||||
{
|
||||
TString query = "USE RMOVIVA\n", queryCust = "USE TRASFATT\n";
|
||||
query << "SELECT (23.REG!=\"\")&&BETWEEN(23.DATAREG,#DADATAREG,#ADATAREG)&&(23.TIPO=\"" << tipocf << "\")";
|
||||
queryCust << "SELECT BETWEEN(DATAREG,#DADATAREG,#ADATAREG)&&(TIPO=\"" << tipocf << "\")";
|
||||
|
||||
if(codcf > 0)
|
||||
{
|
||||
query << "&&STR((23.CODCF=#CODCF))";
|
||||
queryCust << "&&STR((CODCF=#CODCF))";
|
||||
}
|
||||
|
||||
switch(cod)
|
||||
{
|
||||
case toSend:
|
||||
query << "&&((23.TFINVIO=\"\")||(23.TFINVIO=\"X\")||(23.TFINVIO=\"F\"))";
|
||||
queryCust << "&&((TFINVIO=\"\")||(TFINVIO=\"X\")||(TFINVIO=\"F\"))";
|
||||
break;
|
||||
case sent:
|
||||
query << "&&(23.TFINVIO=\"I\")";
|
||||
queryCust << "&&(TFINVIO=\"I\")";
|
||||
break;
|
||||
case disabled:
|
||||
query << "&&(23.TFINVIO=\"N\")";
|
||||
queryCust << "&&(TFINVIO=\"N\")";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
query << "\nJOIN MOV INTO NUMREG==NUMREG\n";
|
||||
queryCust << "\nFROM NUMREG=" << MOV_CUSTOM;
|
||||
|
||||
c_rmoviva = new TISAM_recordset(query);
|
||||
c_trasfatt= new TISAM_recordset(queryCust);
|
||||
|
||||
if(dal.empty()) dal = "20170101"; // Data in cui questo modulo è diventato valido
|
||||
if(al.empty()) al = TODAY;
|
||||
|
||||
c_rmoviva->set_var("#DADATAREG", dal);
|
||||
c_rmoviva->set_var("#ADATAREG", al);
|
||||
c_trasfatt->set_var("#DADATAREG", dal);
|
||||
c_trasfatt->set_var("#ADATAREG", al);
|
||||
|
||||
if(codcf > 0)
|
||||
{
|
||||
c_rmoviva->set_var("#CODCF", codcf);
|
||||
c_trasfatt->set_var("#CODCF", codcf);
|
||||
}
|
||||
|
||||
int items = c_rmoviva->items() + c_trasfatt->items();
|
||||
if(items > 0)
|
||||
{
|
||||
_newMov = true;
|
||||
_newCust = true;
|
||||
return items;
|
||||
}
|
||||
return -1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user