campo-sirio/src/tf/tf0200.cpp
mtollari f5ad9b6e81 Patch level : 12.0 384
Files correlati     : tf
Commento            : 
- Aggiunta nuovo modulo TF, con programma Liquidazione IVA Periodica
- Aggiunta tabelle f173 e f174, la prima per il trasferimento fatture (in lavorazione) e la seconda per questo nuovo programma

git-svn-id: svn://10.65.10.50/branches/R_10_00@23760 c028cbd2-c16b-5b4b-a496-9718f37d4682
2017-04-28 15:14:33 +00:00

590 lines
16 KiB
C++

#include <relapp.h>
#include <automask.h>
#include <config.h>
#include <progind.h>
#include <recarray.h> // cache()
#include <recset.h> // TISAM_recordset
#include <rmoviva.h>
#include <utility.h>
#include "cglib03.h"
#include "tf0.h"
#include "tf0200a.h"
#define CAMPI_CON_BOOLEAN F_TOTOPATT
// ComLiqPerIva: Comunicazione Liquidazioni Periodiche IVA
/** Utilities **/
// Ritorna un cursore di tab.PRM
const TCursor getPRM(int anno)
{
static TRelation rprm(LF_TAB);
TRectype from(rprm.curr()); from.put("COD", "PRM");from.put("CODTAB", anno);
TRectype to(rprm.curr()); to.put("COD" , "PRM");to.put("CODTAB", anno);
TCursor cprm(&rprm, "", 1, &from, &to);
return cprm;
}
// Ritorna il record richiesto di tabcom.LIM
const TRectype getLIM(int anno, int mese)
{
TString key; key << anno;
if(mese < 10)
key << "0" << mese;
else
key << mese;
return cache().get("LIM", key);
}
// Ritorna il record richiesto di tabcom.LIA
const TRectype getLIA(int anno)
{
TString key; key << format("%05d", prefix().firm().codice()) << anno; // %05d Crea un numero di 5 cifre partendo dal codice e mettendoci 0 davanti
return cache().get("%LIA", key);
}
// Ritorna il record valido richiesto di tabcom.VER
const TRectype getVER(int anno, int mese)
{
// Questa tabella ha come chiave l'inizio validità, creo un cursore e scorro finche non trovo l'ultimo periodo valido
static TRelation rver(LF_TABCOM);
static TRectype from(rver.curr()); from.put("COD", "VER");
static TRectype to(rver.curr()); to.put("COD" , "VER");
static TCursor cver(&rver, "", 1, &from, &to);
// Costruisco il controllo sulla chiave
TString key; key << anno;
if(mese < 10)
key << "0" << mese;
else
key << mese;
TRectype rowRet(LF_TABCOM);
for(cver = 0; cver.pos() < cver.items(); ++cver)
{
TRectype rowVer = cver.curr();
if(rowVer.get("CODTAB") < key)
{
rowRet = rowVer;
}
else
break;
}
return rowRet;
}
// Scopiazzata brutalmente da cg4304.cpp
int calc_inc_diff(int anno, int mese, int tipoiva, real& imponibile_diff, real& imposta_diff, real& imponibile_xcas, real& imposta_xcas)
{
CHECKD(tipoiva == 1 || tipoiva == 2, "Bad tipo iva:", tipoiva);
int flag = 0;
imponibile_diff = imposta_diff = imponibile_xcas = imposta_xcas = ZERO;
TString limit; limit << "ANNOLIQ=" << anno;
if (mese < 13) limit << " MESELIQ=" << mese;
TString query; // righe pagamento (TIPOMOV>=3) ed escluse NC!
query << "USE IVADIFF KEY 2 SELECT (TIPOMOV>2)&&(TIPOIVA=" << tipoiva << ")"
<< "\nFROM " << limit << "\nTO " << limit;
TISAM_recordset id(query);
const TRectype& rec = id.cursor()->curr();
for (bool ok = id.move_first(); ok; ok = id.move_next())
{
const real iva = rec.get_real(RMI_IMPOSTA);
const real imp = rec.get_real(RMI_IMPONIBILE);
if (!iva.is_zero() || !imp.is_zero())
{
const int tipodiff = rec.get_int("TIPODIFF");
switch (tipodiff)
{
case 1: imponibile_diff += imp; imposta_diff += iva; break;
case 2: imponibile_xcas += imp; imposta_xcas += iva; break;
default: break;
}
flag |= tipodiff;
}
}
if (tipoiva == 2)
{
real perc_prorata;
query = "USE PLM";
query << "\nFROM CODTAB=" << anno << "\nTO CODTAB=" << anno;
TISAM_recordset ip(query);
const TRectype& recp = ip.cursor()->curr();
for (bool ok = ip.move_first(); ok && perc_prorata == ZERO; ok = ip.move_next())
{
int m = atoi(ip.get("CODTAB").as_string().mid(10));
real p = ip.get("R12").as_real();
if (m == mese && p != ZERO)
perc_prorata = p;
}
if (perc_prorata > ZERO)
{
real ind = imposta_diff * perc_prorata / CENTO;
ind.round(TCurrency::get_firm_dec());
imposta_diff -= ind;
ind = imposta_xcas * perc_prorata / CENTO;
ind.round(TCurrency::get_firm_dec());
imposta_xcas -= ind;
}
}
return flag;
}
/* Da errori in allocazione TArray
const TISAM_recordset getCurIvaXCassa(TDate data_da, TDate data_a, TString codreg_att)
{
TString query = "USE IVADIFF SELECT (BETWEEN(DATAREGP,#DAL,#AL))&&(MOV.REG=#REG)&&(STR((MESELIQ<13)&&(TIPOMOV>2)&&(MOV.TOTDOC!=0)&&(IMPOSTA!=0)&&NUM(INDETR!='X')))";
query << "\nBY DATAREGP DATAREG NUMPRO";
query << "\nJOIN MOV INTO NUMREG==NUMREG";
query << "\nJOIN CLIFO TO MOV INTO TIPOCF==TIPO CODCF==CODCF";
TISAM_recordset id(query);
id.set_var("#DAL", data_da);
id.set_var("#AL", data_a);
id.set_var("#REG", codreg_att);
return id;
}
*/
class ComLiqPerIva_mask : public TAutomask
{
protected:
bool mensile;
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void extractinator();
public:
ComLiqPerIva_mask() : TAutomask("tf0200a") { first_focus(F_ANNO); }
};
bool ComLiqPerIva_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_ANNO:
if(e == fe_modify)
{
TString cod = get(F_CODDITTA); cod << get_int(F_ANNO);
if(cache().get("%LIA", cod).empty())
{
warning_box("Attenzione anno di liquidazione non presente");
set(F_ANNO, "");
break;
}
if(cache().get("%LIA", cod, "S7") == "M")
{
mensile = true;
enable(F_MESE);
disable(F_TRIMESTRE);
}
else
{
mensile = false;
disable(F_MESE);
enable(F_TRIMESTRE);
}
// Abilito i campi a schiena
for(int i = F_SUBFORNITURE; i <= F_VEREFF; i++)
{
enable(i);
if(i >= CAMPI_CON_BOOLEAN)
{
//enable(i + 50); Anche disabilitati funzionano
}
}
}
break;
case F_MESE:
if(e == fe_modify)
set(F_TRIMESTRE, (get_int(F_MESE) - 1) / 3 + 1);
break;
case F_TRIMESTRE:
if(e == fe_modify)
set(F_MESE, get_int(F_TRIMESTRE) * 3);
break;
case DLG_RECALC:
// Vado a prendere i dati di quel mese dalla liquidazione IVA
if(e == fe_button)
{
// Controllo che non ci sia già
if(!cache().get(LF_IVALIQ, TString(get(F_ANNO)) << "|" << get(F_MESE)).empty())
{
if(!yesno_box("Sono già stati elaborati questi dati, si desidera ricalcolarli?"))
break;
}
extractinator();
}
break;
case DLG_EMAIL:
// Richiamo il programma di invio
// TExternal_application app;
break;
}
if(o.dlg() >= CAMPI_CON_BOOLEAN && e == fe_modify) // Se l'utente modifica manualmente uno dei campi calcolati da Campo flaggo il DB
{
set(o.dlg() + 50, "X");
}
// Controllo sull'aggiornamento di campi collegati ad altri
if(e == fe_modify)
{
switch(o.dlg())
{
// Iva Esigibile VS Iva Detratta
case F_IVAES :
case F_IVAESXC :
case F_IVAESDIFF :
case F_IVADET :
case F_IVADETXC :
case F_IVADETDIFF :
{
real ivaes = get_real(F_IVAES) + get_real(F_IVAESXC) + get_real(F_IVAESDIFF);
real ivadet = get_real(F_IVADET) + get_real(F_IVADETXC) + get_real(F_IVADETDIFF);
if((ivaes - ivadet) >= ZERO)
{
set(F_IVADOV, ivaes - ivadet);
set(F_IVADOVC, ZERO);
}
else
{
set(F_IVADOV, ZERO);
set(F_IVADOVC, (ivaes - ivadet) * -UNO);
}
}
// IVA da versare VS a credito
case F_IVADOV :
case F_DEBPREC :
case F_INTLIQTRI :
case F_IVADOVC :
case F_CREPREC :
case F_CREAPREC :
case F_VEAUE :
case F_CREIMP :
case F_ACCDOV :
{
// Ricalcolo VP13 e VP14
real debito = get_real(F_IVADOV) + get_real(F_DEBPREC) + get_real(F_INTLIQTRI);
real credito = get_real(F_IVADOVC) + get_real(F_CREPREC) + get_real(F_CREAPREC) + get_real(F_VEAUE) + get_real(F_CREIMP) + get_real(F_ACCDOV);
if(debito - credito >= ZERO)
{
set(F_IVAVER, debito - credito);
set(F_IVAVERC, ZERO);
}
else
{
set(F_IVAVER, ZERO);
set(F_IVAVERC, credito - debito);
}
}
}
}
return true;
}
// Funzione che effettivamente estrapola i dati necessari
void ComLiqPerIva_mask::extractinator() // Per gli amici GTFO
{
/* Devo estrapolare più mesi, per farlo vado ciclo n volte (1 o 3) in base se stiamo parlando di trimestralità o meno
* I dati da prelevare saranno in PRM, LIM e %LIA
* In PRM e LIM troverò le informazioni suddivise per mese, mentre in %LIA ho l'anno di liquidazione
*/
int start = mensile ? get_int(F_MESE) : get_int(F_TRIMESTRE) * 3;
int end = mensile ? start : start + 3;
int anno = get_int(F_ANNO);
// Valori da calcolare
real totopatt = ZERO;
real totopattxc = ZERO;
real totoppas = ZERO;
real totoppasxc = ZERO;
real ivaes = ZERO;
real ivaesxc = ZERO;
real ivaesdiff = ZERO;
real ivadet = ZERO;
real ivadetxc = ZERO;
real ivadetdiff = ZERO;
real rettifiche = ZERO;
real varimp = ZERO;
real rimborsi = ZERO;
real impnover = ZERO;
real crespec = ZERO;
real vereff = ZERO;
real ivadov = ZERO;
real ivadovc = ZERO;
real debprec = ZERO;
real creprec = ZERO;
real creaprec = ZERO;
real intliqtri = ZERO;
real accdov = ZERO;
real ivaver = ZERO;
real ivaverc = ZERO;
// Costanti
const TString codreg_att = "VEN";
const TString codreg_pas = "ACQ";
for(; start <= end; start++)
{
TDate data_da(1, start, anno);
TDate data_a(31, start, anno);
/****************************************************************************************************************
* TOTOPATT, TOTOPATTXC, TOTOPPAS, TOTOPPASXC, IVAES, IVAESXC, IVAESDIFF,
* IVADET , IVADETXC, IVADETDIFF
****************************************************************************************************************/
// Riga LIM
const TRectype rowLim = getLIM(anno, start);
// Controllo che la liquidazione è stata effettuata
if(rowLim.empty())
{
error_box("Attenzione non è stata calcolata la liquidazione del periodo corrente");
return;
}
// Riga LIA
const TRectype rowLia = getLIA(anno);
// Calcolo il cursore di PRM
//TCursor curPrm = getPRM(anno);
static TRelation rprm(LF_TAB);
TRectype from(rprm.curr()); from.put("COD", "PRM");from.put("CODTAB", anno);
TRectype to(rprm.curr()); to.put("COD" , "PRM");to.put("CODTAB", anno);
TCursor curPrm(&rprm, "", 1, &from, &to);
for(curPrm = 0; curPrm.pos() < curPrm.items(); ++curPrm)
{
TRectype rowPrm = curPrm.curr();
// Controllo il mese
TString codtab = rowPrm.get("CODTAB");
int app = stoi(rowPrm.get("CODTAB").sub(13,15));
if(stoi(rowPrm.get("CODTAB").sub(13,15)) != start) continue;
// Verifico su che registro mi trovo
if(rowPrm.get("CODTAB").sub(10,13) == codreg_att)
{
totopatt = totopatt + rowPrm.get_real("R0");
}
else if(rowPrm.get("CODTAB").sub(10,13) == codreg_pas)
{
totoppas = totoppas + rowPrm.get_real("R0");
}
}
real appReal = ZERO;
// IVA esigibile
TToken_string tokenPrec = rowLim.get("S0");
tokenPrec.get(0, appReal);
ivaes = ivaes + appReal;
// IVA detraibile
appReal = ZERO; // Nel dubbio azzero
tokenPrec.get(1, appReal);
ivadet = ivadet + appReal;
// Se ha attiva l'IVA x cassa
if(gestione_IVAxCassa(data_da))
{
static TRelation rreg(LF_TAB);
TRectype fromReg(rprm.curr()); fromReg.put("COD", "REG");fromReg.put("CODTAB", anno);
TRectype toReg(rprm.curr()); toReg.put("COD" , "REG"); toReg.put("CODTAB", anno);
// Questo codice è stato preso da print_IVAxCassa in cg4400.cpp
TString query = "USE IVADIFF SELECT (BETWEEN(DATAREGP,#DAL,#AL))&&(MOV.REG=#REG)&&(STR((MESELIQ<13)&&(TIPOMOV>2)&&(MOV.TOTDOC!=0)&&(IMPOSTA!=0)&&NUM(INDETR!='X')))";
query << "\nBY DATAREGP DATAREG NUMPRO";
query << "\nJOIN MOV INTO NUMREG==NUMREG";
query << "\nJOIN CLIFO TO MOV INTO TIPOCF==TIPO CODCF==CODCF";
TCursor curReg(&rreg, "", 1, &fromReg, &toReg);
for(curReg = 0; curReg.pos() < curReg.items(); ++curReg)
{
TRectype rowReg = curReg.curr();
// Siamo su un registro non IVA
int tipo_registro = rowReg.get_int("I0");
if(tipo_registro > 2) continue;
TISAM_recordset id(query);
id.set_var("#DAL", data_da);
id.set_var("#AL", data_a);
id.set_var("#REG", rowReg.get("CODTAB").sub(4));
const TRectype& rec = id.cursor()->curr();
for (bool ok = id.move_first(); ok; ok = id.move_next())
{
if(tipo_registro == 1) // Vendite
{
totopattxc = totopattxc + rec.get_real("IMPOSTA");
}
else // Acquisti
{
totoppasxc = totoppasxc + rec.get_real("IMPOSTA");
}
}
}
// IVA esigibile
TToken_string tokenPrec = rowLim.get("S0");
tokenPrec.get(0, ivaes);
real imponibile_diff, imposta_diff, imponibile_xcas, imposta_xcas;
calc_inc_diff(anno, start, 1, imponibile_diff, imposta_diff, imponibile_xcas, imposta_xcas);
// IVA detraibile
tokenPrec.get(1, ivadet);
calc_inc_diff(anno, start, 2, imponibile_diff, imposta_diff, imponibile_xcas, imposta_xcas);
}
/** Resto *****************************************************************************************************/
ivaes = ivaes + rowLim.get_real("R13");
ivadet = ivadet + rowLim.get_real("R12");
rettifiche = rettifiche + rowLim.get_real("R5");
varimp = varimp + rowLim.get_real("R17");
rimborsi = rimborsi + rowLim.get_real("R1");
impnover = impnover + rowLim.get_real("R18");
crespec = crespec + rowLim.get_real("R19");
vereff = vereff + rowLim.get_real("R8");
debprec = debprec + rowLim.get_real("S2");
appReal = ZERO;
// Credito periodo precedente
tokenPrec.get(2, appReal);
creprec = creprec + appReal;
// Credito anno precedente
creaprec = creaprec + rowLia.get_real("R0");
intliqtri = intliqtri + rowLim.get_real("R14");
accdov = accdov + rowLim.get_real("R11");
}
// Controllo debprec
// Calcolo prendendo dalla tabella %VER
TRectype rowVer = getVER(anno, start);
if(rowVer.empty() || rowVer.get_real("R5") == ZERO)
{
error_box("Non è stata valorizzato correttamente il campo \"Periodico\" in \"Versamenti ed interessi IVA\"");
return;
}
else
{
if(debprec > rowVer.get_real("R5")) // Se è maggiore di 25.82€ va azzerato
debprec = ZERO;
}
// Imposto tutti i campi
set(F_TOTOPATT, totopatt);
set(F_TOTOPATTXC, totopattxc);
set(F_TOTOPPAS, totoppas);
set(F_TOTOPPASXC, totoppasxc);
set(F_IVAES, ivaes);
set(F_IVAESXC, ivaesxc);
set(F_IVAESDIFF, ivaesdiff);
set(F_IVADET, ivadet);
set(F_IVADETXC, ivadetxc);
set(F_IVADETDIFF, ivadetdiff);
// Iva dovuta o a credito
if(ivaes - ivadet > ZERO)
{
ivadov = ivaes - ivadet;
set(F_IVADOV, ivadov);
set(F_IVADOVC, ZERO);
}
else
{
ivadovc = ivadet - ivaes;
set(F_IVADOV, ZERO);
set(F_IVADOVC, ivadovc);
}
set(F_DEBPREC, debprec);
set(F_CREPREC, creprec);
set(F_CREAPREC, creaprec);
//set(F_VEAUE, veaue); // Campi non calcolati, messi qua per un eventuale futuro
//set(F_CREIMP, creimp);
set(F_INTLIQTRI, intliqtri);
set(F_ACCDOV, accdov);
// Calcolo l'IVA da versare o a Credito
ivaver = (ivadov + debprec + intliqtri) - (ivadovc + creprec + creaprec + get_real(F_VEAUE) + get_real(F_CREIMP) + accdov);
ivaverc = (ivadovc + creprec + creaprec + get_real(F_VEAUE) + get_real(F_CREIMP) + accdov) - (ivadov + debprec + intliqtri);
if(ivaver >= ZERO)
set(F_IVAVER, ivaver);
else
set(F_IVAVERC, ivaverc);
set(F_RETTIFICHE, rettifiche);
set(F_VARIMP, varimp);
set(F_RIMBORSI, rimborsi);
set(F_IMPNOVER, impnover);
set(F_CRESPEC, crespec);
set(F_VEREFF, vereff);
// Azzero i booleani
for(int i = B_TOTOPATT; i <= B_VEREFF; i++)
{
set(i, "");
}
}
class ComLiqPerIva_app : public TRelation_application
{
private:
ComLiqPerIva_mask* _mask;
TRelation* _rel;
protected:
bool user_create();
bool user_destroy();
virtual TMask* get_mask(int mode) { return _mask; }
public:
virtual TRelation* get_relation() const {return (TRelation*)_rel;}
};
bool ComLiqPerIva_app::user_create()
{
_rel = new TRelation(LF_IVALIQ);
_mask = new ComLiqPerIva_mask;
set_search_field(F_ANNO);
return true;
}
bool ComLiqPerIva_app::user_destroy()
{
delete _mask;
return true;
}
int tf0200(int argc, char* argv[])
{
ComLiqPerIva_app app;
app.run(argc, argv, TR("Trasferimento dati liquidazione IVA"));
return 0;
}